C# Short Posts 🔞 – Telegram
C# Short Posts 🔞
250 subscribers
111 photos
4 videos
151 links
Здесь я, Дима Афонченко @Undermove1, публикую короткие заметки о разработке (и около). Я не претендую на правильность высказываний и открыт к дискуссиям, исправлениям и конструктивной критике. С любыми деструктивными вещами можно приходить в комменты)
Download Telegram
Теперь получилось слово “компаний”. Нам подходит. Можем брать новую фразу и предлагать продолжить её. Разумеется, в реальности нейронка не обучится так быстро. Вначале она довольно долго будет выдавать билиберду, поэтому этот процесс будет происходить миллионы раз по каждому из примеров.

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

И вот тут у меня главная сложность. Для твердого объяснения того, почему результат о страховых компаниях получается неточным, мне бы нужны исходные данные, на которых тренировали GPT.
 
OpenAI не показывает сами данные, на которых училась модель. Зато вот тут описываются методы, которыми тренировали предыдущую версию модели. Поэтому я могу лишь теоретизировать на основе тех ответов, которые возвращает ChatGPT.
👉 Представим, что данные для обучения по страховым компаниям Батуми выглядели вот так:

Aldagi – страховая компания Батуми телефон +995 422 27 27 27 – повторяется в выборке 100 000 раз
GPI Holding – страховая компания телефон +995 634 13 29 45 – повторяется в выборке 500 раз
Imedi L – страховая компания +995 345 13 12 22 – повторяется в выборке 100 раз.
Pasha Insuranse – страховая компания Батуми +995 125 83 39 54 – повторяется в выборке 5 раз.
 
Первая компания в обучающей выборке попадается 100 000 раз. Это значит, что при обучении чату ГПТ буквально говорят: вероятность выпадения комбинации цифр +995 422 27 27 27 при упоминании слов "Батуми" и "Страховая компания" в 200 раз выше, чем комбинации "+995 634 13 29 45"
 
Это не значит, что чатГПТ так и решит, что надо выдавать эти цифры, просто вероятность этих цифр будет сильно выше. Что мы и видим на скриншоте, там секвенция +995 422 27 27 27 повторяется довольно часто и для разных компаний.
Please open Telegram to view this post
VIEW IN TELEGRAM
🅰️ Итого: Что важно понимать – у ChatGPT нет данных за 2021 год. У него есть весовые коэффициенты, есть словарь токенов, но самих данных нет! Это одна из тех сложностей, которая приводит к коллизиям, когда кто-то просит удалить из нейронки некоторые данные. Это сделать невозможно! Потому что данных нет. Есть таблицы с цЫфрами, и есть таблицы с обрывками слов, но самих данных нет. 🥷

Именно поэтому задачи на агрегацию данных ChatGPT решает не лучше, чем игральный кубик решает примеры на умножение. То есть вы можете выбросить верный ответ, но это будет везением, а не законоерным результатом.
🔥21👍1
🤔 Почему ChatGPT может то что может. Часть 8. Как сделать ответы правильными. Плагины.
Когда я только начал писать эту серию постов, у ChatGPT вышли плагины. Это именно то, что нужно.

Раньше мы могли взять сгенерированную ChatGPT строчку и пойти в интернет, чтобы факт-чекнуть то, что выдал нам злой ИИ. Но теперь, с помощью плагинов, он это может делать сам.
 
То есть в случае с плагинами, мы попросим чат выдать нам список из 10-ти страховых компаний. Он сгенерирует какую-то чушь, а затем пойдет в поисковую истему с вопросом: "Существует ли страховая компания Aldagi в Батуми?" И если ответ будет да, то он вытащит сам из поисковой выдачи нужные данные и подправит свою строку.

В этом случае, мы действительно будем работать с данными, которым можно доверять. И вот это уже неверотно круто!

🅰️Итого: мы теперь знаем как устроены простые нейроны, как работает ChatGPT, как его учат, и как плагины вылечивают случайный характер ответов от нейронки. Думаю что через некоторое время появится куча надстроек, которые сделают ChatGPT еще более магическим, и надеюсь, что эти посты как-то помогут развеять эту магию.

P.S.: Ффух. На этом всё. Я уже давал себе зарок не писать длинные серии статей. Но очень интересно было разбираться с тем, как всё это работает.

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

Ну и пишите в комментах и в личку, если знаете лучше меня, как это всё работает. Я часто делаю ошибки, но всегда стараюсь их признавать и исправлять.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
🧑‍🚀Proxyman – debugging proxy для тех кто в маке.
Короче, есть такие штуки, которые делают тебе стыдно. Ты их осваиваешь, и понимаешь, что должен был сделать это еще в первый год разработки.
 
Вот я к примеру только недавно научился пользоваться debugging proxy тулзой. Это приложуха, которая позволяет просматривать http-запросы, которые идут между приложением и сервером. Короче, если вы как и я сидите на маке и еще не юзаете такое, то прорекламирую Proxyman:
1️⃣ Супер-удобно видеть историю запросов и ответов. Раньше я просто запускал всё под дебагом, сохранял скриншоты ответов серсвера в блокнотике и сравнивал.
2️⃣ Позволяет чуть лучше разобраться с ситуациями, когда вызов по каким-то причинам не доходит до контроллера. Посмотреть, вылетели ли пули, и если вылетели, то куда попали.
3️⃣ Также в Proxyman можно взять запрос из истории, поменять в нём несколько параметров и отправить заново. Это удобно, когда в запросе дохрена данных, а для теста нужно только маленький поменять.
4️⃣ Легко по нажатию одной кнопки подкладывает SSL сертификаты для указанных сайтов и это позволяет смотреть зашифрованный трафик.
 
Бесплатная версия довольно функциональная. Лично я пока не почувствовал, что её ограничения мешают работе.

P.S.: На винде аналог этой штуки – Fiddler. Но на маке он платный, требует регистрации, и после окончания триального периода не работает.

P.P.S.: Очень большое спасибо Степе Гранкину, который целый год размахивал передо мной фиддлером, а я всё прокрастинировал освоение этой штуки, потому что "на маке никак аналогов не могу найти". Я просто не искал, каюсь. Но вы не повторяйте моих отмазок.
#инструменты
🔥6👍1
😑 Как я ошибся про async await в однострочных методах.

Как-то год назад думал над такой штукой, как async/await в однострочных методах. Я тогда сходил в sharplab.io посмотрел, что добавление оных в однострочных методах создает лишнюю, как мне тогда казалось стейт-машину, и сделал крайне поспешный вывод, что в однострочных методах async/await не нужен.

Я был не прав.

Точнее не совсем прям не прав, но не совсем уж прав. Про лишнюю стейт-машину и про потерю производительности пожалуй прав, но с точки зрения отладки есть ряд ньюансов:

1️⃣ Асинхронные и синхронные исключения нормализуются для того, чтобы всегда быть асинхронными.
2️⃣ Код становится проще изменять (например, можно добавить оператор using).
3️⃣ Отладка асинхронных методов становится проще (поиск зависаний и т.д.).
4️⃣ Исключения, выброшенные, будут автоматически обернуты в возвращаемую задачу (Task), вместо того чтобы неожиданно возникать у вызывающего кода.
5️⃣ AsyncLocals не будут выходить за пределы асинхронных методов. Если вы устанавливаете асинхронную AsyncLocal в неасинхронном методе, она "утечет" из этого вызова.
 
Что такое AsyncLocals я хз. Но когда что-то утекает – это точно нехорошо.
 
🅰️ Итого: В однострочных методах стоит предпочитать употребление async await, но если вам нужна производительность и пофиг на вышеозначенные факторы, то можете не употреблять.
 
P.S.: Спасибо Арсению Кравченко, который мне на всё это указал в очередном из наших горячих споров.
#опыт
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🔥1
🛩 Маленький лайфхак на случай если проверка не проходит.

Что меня изрядно подзаёбывает в ASP_NET так это то, что порой брекпоинт в контроллере по какой-то причине может не остановиться под отладкой.

Куча каких-то надстроек, в которых всё может сломаться. Вот одна из таких настроек – валидатор моделек. Проверяет вашу модельку, упрощая ваш код на одну строчку:
if (ModelState.IsValid){
return BadRequest(ModelState);
}


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

services.Configure<ApiBehaviorOptions>(
options=> {
options.SuppressModelStateInvalidFilter=true;
});

#инструменты
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍21
7️⃣ Интуиция. Системы её развивающие и убивающие.
Вот вам маленький прикольный факт из книжки Канемана "Думай медленно решай быстро": существуют системы, которые интуицию развивают, а есть те, которые развивают ощущение, что интуиция развивается, но на самом деле делают всё только хуже.
 
Канеман пишет, что система развивающая интуицию соответствует двум характеристикам:
 
1️⃣ Быстрая обратная связь.
2️⃣ Наличие стабильных закономерностей в изучаемой среде
 
Как пример такой идеальной среды Канеман приводит Шахматы🐴

1️⃣ Результат виден на доске сразу, а не через неделю/год/долгое время
2️⃣ Правила шахмат не меняются от партии к партии.
 
Человек учится играть в шахматы примерно так же как учится читать. Читать мы учимся сначала по буквам, потом по словам, затем целыми предложениями. Так же и с шахматами: сначала ходы, потом комбинации, а потом целые партии.
 
😮 Если же этих двух условий нет, то можно встретиться с таким опасным явлением, как "иллюзия навыка". Это когда вы думаете, что правильно прогнозируете что-то, но на самом деле просто играете в рулетку.
 
Как пример такой системы Канеман приводит рентгенологов. Навык интуции в этой области очень тяжело развить, потому что здоровье пациента может не меняться годами, и вообще доктор может не узнать о результатах некоторых своих предположений, если пациент, к примеру сменит место жительства.

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

🅰️ Итого: Если полагаетесь на свою интуцию, будет полезным проверить, в какой среде она развивалась. Не случилось ли так, что вы попали в ловушку иллюзии навыка?
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1🔥1
🏆 Как я сделал систему достижений для Тралебота

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

Коротко расскажу, что хотелось, и как получилось:
Хотелось:
1️⃣ Чтобы проверку ачивки можно было бы вызвать одной строчкой.
2️⃣ Всю систему должно быть легко выделить в отдельный сервис и дергать по АПИ.
3️⃣ Не нужно мигрировать базу, если название ачивки поменялось.
4️⃣ Легко добавить новую ачивку в виде класса с условиями проверки.
5️⃣ Если нужно, эти классы с условием проверок можно превратить во что-то более абстрактное и хранить в базе данных.
6️⃣ Несложно сделать переводы ачивок на разные языки при случае.
7️⃣ Можно посмотреть открытые и не открытые ачивки, но хранить в базе для пользователя только открытые.

Получилось так:
Создал три верхнеуровненвые абстракции: IAchievementsService, IAchievementChecker<TTrigger>, IAchievementTrigger,

Вот как они связаны:
К примеру мы хотим наградить человека за то, что он получил 10 золотых медалей медалей.
1️⃣ Вытаскиваем из базы сколько медалей он получил и отправляем триггер с этой информацией в achievementService:

var wordMasteringLevelTrigger = new WordMasteringLevelTrigger
{
GoldMedalWordsCount = goldMedalsCount,
};

await _achievementsService.AssignAchievements(wordMasteringLevelTrigger,request.UserId,ct);

2️⃣ Сам achievementService пробегается по куче разных чекеров и смотрит, подошло ли условие одного из них.

private readonly IEnumerable<IAchievementChecker<IAchievementTrigger>> _achievementCheckers;

private List<Achievement> AssignAchievements <T> (T trigger, User user)
{
var unlockedAchievements = new List<Achievement>();

foreach (var achievementChecker in _achievementCheckers)
{
if( achievementChecker is {} checker
&& checker.CheckAchievement(trigger))
{
var achievement = checker.MapToAchievement();
unlockedAchievements.Add(achievement);
}
}

\\ тут еще код, который достает из базы
\\ уже открытые ачивки и клеит их с новыми

return unlockedAchievements;
}

3️⃣ Код IAchievementChecker, содержит информацию о названии ачивки, иконку и условие проверки. Выглядит вот так:

public class MedalistChecker: IAchievementChecker<WordMasteringLevelTrigger>
{
public string Icon => "🥉";
public string Name => "Медалист";
public string Denoscription => "10 слов с золотой медалью";
public Guid AchievementTypeId => Guid.Parse("574316E8-E3BA-4BD1-92DB-61409C85E0ED");
public bool CheckAchievement(object trigger)
{
if (trigger is not WordMasteringLevelTrigger kingOfScoreTrigger)
{
return false;
}

var medalWordsCount = kingOfScoreTrigger.GoldMedalWordsCount;
return medalWordsCount>=10;
}
}

📝 Есть пара вещей, которая меня смутила, но я так и не понял, плохо это или хорошо:
1️⃣ Внутри чекера хранится и описание ачивки и код проверки. Что-то в этом есть крамольное, но пока не знаю, что.
2️⃣ Бывает за один юзкейс нужно вызвать этот AssignAchievements() аж три раза. Не каждый вызов идет в базу, но код хэндлеров наполняется вызовами AssignAchievements, не имеющими прямого отношения к логике. Вынести их в бихейвиор или что-то такое, тоже проблематично, потому в юзкейсах есть ифчики, внутри которых я вызываю эти самые методы проверки.

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

🅰️ Итого: Вообще звучит, как неплохая задачка для собеса. Хз, прошел бы я с таким решением куда-то или нет, но как минимум сам себя в свой стартап я бы точно устроил 😈
Please open Telegram to view this post
VIEW IN TELEGRAM
🏆3👍2🔥2
👨‍🎨 System Десигн.

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

Я не то чтобы спорил с этим мнением, но скорее не понимал, что не устраивает критикующих. А тут ютубчик подкинул мне видосики вот этого чувака System design interview: "Design Telegram" (with ex-Google EM) .

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

1️⃣ Проясняешь вопросы
🔘 Пару минут спрашиваешь интервьюера о задаче
🔘Стараешься ограничить область проблемы
🔘Спрашиваешь, какие фичи хочется реализовать (функциональные требования)
🔘Потом спрашиваешь нефункциональные требования (скорость ответа, там консистентность и так далее)
🔘Все это ты можешь сам предложить, и продать интервьюеру.

2️⃣ Набрасываешь верхнеуровневый дизайн 🪐
🔘Определяешь одну две метрики, к примеру QSP (query per second)
🔘Набрасываешь компоненты верхнеуровнево (вот тут интересно было сравнить фейсбучного разработчика и гугловского.)
🔘В этом этапе главное -- думать так, что типа каждый компонент хорошо выполняет свою функцию. Типа не размышлять над тем, а что будет если кэши разъедутся. Надо просто типа обозначить "вот кеширующий слой"

3️⃣ Дальше идет углубление. (Drill down 🛠)
🔘Тут уже попроще, просто расписываешь один компонент. Можно не сильно связывать его с предыдущей схемой. Это может быть отдельная схема. Главное рассказать, как компонент работает. Тут не нужно упоминать конкретные технологии, нужно обозначать компоненты схематично "какая-то очередь"

4️⃣ Тебе подсовывают ботлнек. 🍾
🔘Теперь можно поговорить о том, какие технологии будут этот ботлнек обслуживать. К примеру тебе говорят, что нагрузка повышается. Ты говоришь, что вот эта очередь будет кафкой, и в случае увеличения нагрузки, мы повысим количество кафка-нод.

Не супер-магия вроде. Понятно, что вышеописанное — это иллюстрация мема про сову, но тем не менее. Просто я как-то смотрел интервью, где чувак сразу дизайнит систему с конкретными технологиями. И это вызывало глубокое чувство экзистенциальной нестабильности (вахуе я был короче)
#systemdesign
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41👍1
🏎 Что быстрее Single или First?

Обожаю такие штуки. Что быстрее Single или First при запросах через Entity Framework?

🅰️Оказалось, что эквипенисуально! ⚖️
Типа First побыстрее маленько, но там порядки такие:
Single: 2.609 ms
First: 2.602 ms

Ну то есть это такие порядки, что, если они вас интересуют, то вам вообще пора бы видимо решать не между First и Single, а вообще использовать ли EF дальше 😃

P.S. Классный чувак Derek Comartin! Пока что это мой топ-блоггер по C# среди всех англоязычных чуваков!
Вот полный видос, но суть я уже заспойлерил 😛
Single() or First()? Understand the abstractions you use!
#benchmarks #бенчмарки
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1👾1
💿 Как дискорд переехал на новую базу

Наткнулся на видос, где рассказывается, как Discord мигрировал 173 триллиона сообщений из CasandraDB в ScyllaDB.

🅰️ Если коротко говорить, то:

1️⃣ Написали промежуточный слой между сервисами и базой. Назвали его DataServices. Cервисы стали ходить в этот слой, вместо прямых вызовов в базу. Сам DataServices написали на Rust. Еще этот слой кэшировал входящие запросы. Так что, если несколько сервисов просили одни и те же данные, то в базу совершался только один поход.

2️⃣ Еще одна штука была в том, что им временами не хватало скорости SSDшек, которые были на серверах со Scylla и поэтому они скомбинировали работу SSD с Google Persistant Disk. На GPD шли запросы на запись, а с SSD шли запросы на чтение.

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

💋 Мне как любителю надежности и спокойной разработки отдельно понравилось, что у Discord есть принцип Safe Rollback, о том, что все изменения нужно делать откатываемыми. То есть, если задеплоил что-то поломанное, то всегда должен иметь возможность откатить по одной кнопке. Поддерживаю такое.
#systemdesign
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3🏆1
🫡 Почему Кафка такая быстрая

Уже несколько дней попадаются видосы с канала ByteByteGo.

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

От себя скажу: блинский, это ж ваще офигенский топик (все поняли каламбур? типа кафка топики и вот это все) для видоса!

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

🅰️ Оказалось дело в двух концептах:

1️⃣ Sequential доступ к памяти вместо Random. 🧠 Это означает, что кафка не разбрасывает байты по памяти, а хранит все данные рядом на диске. Вот тут-то и пригождаются базовые знания о работе операционок и обо всем таком

2️⃣ Zero copy принцип. ©️🚫 А второе означает, что чуваки избегают копирования везде, где это возможно.

К примеру, перед тем как отправить данные в сеть, обычно ваши данные копируются сначала в Socket Buffer а оттуда отправляются в NIC (Network Interface Cord) Buffer. Кафка избегает этого копирования и пихает данные напрямую в NIC Buffer. И таким образом она поступает везде, где есть буфера. Она их избегает по возможности.

Это две главных фичи. Думаю, что есть и другие, но эти вот самые самые. Тут в видосе есть больше картинок, но суть та же.
#kafka
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91🤔1
👨‍💻 Как это работает? Делаем курьера на карте в мобильном приложении Додо (Пояснительный дикпик)
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻 Как это работает? Делаем курьера на карте в мобильном приложении Додо
Вот уже третью неделю тусуюсь в новой команде. Делаем клиентские штуки. Для меня это в новинку, так как до этого я разрабатывал в основном для нашей кухни.

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

Тут я вкратце запишу все это, так сказать от первого лица.

😑 Как принималось решение?
Вышел на одном из корпоративов Федор и сказал: "Ребяты, наше приложение в пицце — говно. Все переделываем!" (ну он не так сказал, но, вы понимаете)

Все зашевелились и впали в неистовство (охуели). Я тоже не остался в стороне (охуел и зашевелился). Потому что наряду с этим Федор еще сказал, что разработку моих любимых кухонных сервисов мы немного замедляем. Тут я подумал "Куда уж медленнее?!"

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

Тут нужно оговориться, что в общении с ребятами в компании, я выяснил, что переработка приложения уже давно в планах, а Федор просто дал волшебного пенделя. Но я, как увидел, так и пишу 🤷‍♀️

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

Вообще для полезности задач существует модель Нориаки Кано, где задачи делятся на
🔘 Обязательные - их нельзя не сделать. Без них вашим продуктом невозможно пользоваться.
🔘 Конкурентные - у всех есть, но их надо делать лучше, чем у других
🔘 Привлекательные - они вызывают ВАУ эффект. Пользователь такого не ожидал. Ни у кого нет.
🔘 Нейтральные - ничего не вызывают у пользователя.
🔘 Вредные - это то, что портит пользовательский опыт. Такие задачи делать не надо.

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

👨‍🎨 Как разрабатывается дизайн?
У нас есть крутейшая design lead Яна Мишко и она провела крутейшее исследование конкурентов. Его результат представляет из себя дерево User Flow, где расписаны все крайние случаи использования фичи у всех остальных доставок. Что будет если сделают два заказа? Как ведет себя экран, когда заказ отменяют? И так далее.

На таком дереве легко видеть узлы, в которых можно придумать что-то новенькое. Короче, это прям красиво и математично. А еще говорят, что дизайн -- гуманитарная дисциплина!

Дальше мы определили контуры нашей будущей фичи и перешли к технической проработке. И тут мы переходим к части:

Как такие вещи устроены технически?
Я угрюмый бэкендер и у меня были сомнения в том, что такую фичу можно сделать быстро. Но в целом, оказалось, что все не настолько сложно. Принципиальная схема оказалась легкой (пояснительный дикпик выше):
1️⃣ Курьерское приложение отправляет координаты курьера в Azure IoT Hub
2️⃣ У хаба есть настройка, которая позволяет перенаправлять события в Kafka. Как оказалось это делает одной кнопкой
3️⃣ Из кафки событие попадает в сервис Recent-Orders и прикапывается в базку. Это специальный сервис, который оперативно отдает данные по заказу.
4️⃣ При запросе от мобильного приложения или сайта Mobile API и Site API получают данные о координатах из Recent-orders и отдают их обратно клиентам.

По итогу получается, что со стороны бэка выглядит, как действительно быстрая победа (классическое приключение на 20 минут). Посмотрим, что из этого выйдет, но пока вот так. Я все еще скептически смотрю на эту фичу, с точки зрения произведения ВАУ на пользователя или какой-то видимой пользы. Но попробуем и посмотрим, как оно пойдет. Мне то, что? Будет чем повыебываться на пьянках))) А то всё "ну я для кухни делал в основном фичи 😕"
#опыт
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5😎3👍1
🕋 Изолируйте компонентные тесты
Перешел тут в новую команду и столкнулся с интересным решением. Возможно оно было сделано по рациональным причинам, но все же предостерегу всех от подобного.

💁‍♀️ В чем суть. Есть у нас компонент Site API. В нем есть разные тесты. Юнитовые, конпонентные, интеграционные. Обычно у нас принято, что перед запуском компонентных тестов, мы запускаем docker-compose файлик, где содержатся все зависимости сервиса. В более технически зрелых проектах используются dotnet-testcontainers.

Сделал фичу, хочу запустить компонентные тесты:
Поискал глазами файлик — не нашел. Поискал dotnet-testcontainers — не нашел. Посмотрел в ридмиху. В ней нашел абстрактное объяснение, почему не будет e2e тестов на окружении, но как запустить тесты локально — не нашел. Запускаю тесты. Не проходят. Ругаются на монгу. Пробую запустить в github actions. Все проходит. Иду к коллеге с вопросами. Он предлагает понизить версию библиотеки для монги и вуаля тесты проходят. (тут я говорю: Да какого хуя, блять! 🤬)

Оказалось, что в гитхабовском воркфлоу все же запускается контейнерная версия монги и она подходит под новую версию библиотеки, а локально тесты ходят в настоящую монгу. (тут я говорю: Да почему так-то, блять! 😐)

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

🅰️ В общем, вывод такой:
1️⃣ Лучше сразу в компонентных тестах подменяйте все зависимости изолированно. Используйте dotnet-testcontainers. На крайний случай сделайте docker-compose и в ридмихе напишите, что перед запуском тестов его нужно поднять и приобнять.
2️⃣ Если ваш проект постоянно в авралах, то не разменивайтесь на быстрые решения, и не верьте менеджерам, которые говорят, что дадут вам время на рефакторинг через три месяца после запуска проекта — это все беспардонный обман. (а по факту лютый пиздеж даже не вам, а самому себе)

Такие дела.
#опыт
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1🌚1
👨‍🔧 Делал по коммиту каждый день в течение года и вот что из этого вышло.

Я стал мастером кликбейтных заголовков! Ладно, никто не кликает, никого они не байтят. Простите

Где-то год назад я решил, что попробую делать по одному коммиту в день в свои пет-проекты. Тому было две причины:
1️⃣ Мне нравилось делать TDD каты перед работой. Они хорошо давали размять нейронку и после них кодить было проще. Но в какой-то момент сама вот эта деятельность вхолостую наскучила, и мотивация их делать потерялась. Поэтому нужно было найти достойную замену.
2️⃣ Мне хотелось получить какой-то более-менее объективный инcтрумент, который помогал бы отслеживать уровень так называемого мыслетоплива (это термин Максима Дорофеева, автора книги "Джедайские Техники")

Установил себе несколько правил, чтобы не упарываться и не делать коммиты ради коммитов:
1️⃣ Решил, что буду уделять в день этому делу 15 минут. Но если сделаю коммит раньше и желания что-то делать дальше не будет, то можно расслабиться
2️⃣ Если возникнет желание что-то еще покоммитить, то сдерживать себя не буду.
3️⃣ Если вообще невмоготу, то и хер бы с ним — можно ничего не коммитить.

🅰️ Короче, это оказалось в 100500 раз пизже чем ебАные TDD каты!
🔘Кажется, что 15 минут — это херня. И так оно и есть! Но, если смотреть в разрезе года, то набирается аж 5475 минут или же 91.25 часов! (это как ведьмака пройти!)
🔘За это время я успел намутить себе два пет-проекта, один из которых помогает мне учить английский. TDD каты (ебАные), при всем моем уважении, такого не могут.
🔘Я научился чуть лучше декомпозировать задачи. Потому что приходится каждый раз задавать себе вопрос "что я могу тут полезного сделать за 15 минут".
🔘А еще я отследил наконец свои провалы в мыслетопливе. Вот вы их видите на скрине, с ноября по январь и с апреля по июнь. То есть это значит, что на восстановление мне нужно около 6 недель. В эти периоды нужно брать отпуска и спокойно пережидать, пока все не придет в норму. Ну или можно подумать, как оптимизировать свою работу так, чтобы сократить эти провалы.

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

🅰️ В общем, рекомендую попробовать ежедневный 15-ти минутный подход к коммитам. Может и вам зайдет, а может вы уже и сами что-то похожее делаете. В общем, если кто поделится в личке или комментах, буду мега-признателен 🥰
#личнаяэффективность
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥82👍2
💴 PCI DSS в Додо
Недавно послушал на нашем девфоруме сказ от восхитительного Матвея Григорьева о том, как Додо прошло PCI DSS сертификацию.

Это такая штука, которая нужна всем, кто принимает больше 6 миллионов платежей по карте в год. Додо принимает сильно больше — примерно 40 миллионов платежей в год.

Если ваша компания доросла до таких объемов, то к вам приходит Сбер или другой провайдер и приносит 70 листов требований, о том, как вам нужно безопасно проводить платежные операции.

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

Два основных вывода, которые я сделал для себя из этого доклада:
1️⃣ Облака — это топчик. Всем надо быть в облаках. Если кто-то сомневался, то сомневаться не нужно. Ибо львиная доля сертификации прошла тупо потому, что облачный провайдер сам когда-то прошел сертификацию.
2️⃣ Инженерная культура роляет. Просто из-за того что работающие у нас люди знают базовую гигиену, процесс сильно упрощается. Так что если вы не вкладываетесь в культуру, из-за того что эти инвестиции не окупаются, то технически это правда, а практически это покупает время и нервы.
3️⃣ Кубер — роляет. Я это и так знал, но все же, было классно услышать, о том, как гибкость, которую он дает, помогла быстро занести все нужные компоненты в удовлетворяющий всем условиям контур.

Такие дела. С крутыми людьми работаю, однако.
#опыт
🔥61👍1