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

Собственно это одна из причин, почему ChatGPT отвечает потихоньку, а не всей фразой целиком.
 
Ок. Мы разобрали все аспекты работы ChatGPT. Далее разберёмся с тем, как же он сгенерировал нам список страховых компаний, и почему все эти номера и адреса оказались ненастоящими.
🔥2👏1🤩1
🤔 Почему ChatGPT может то что может. Часть 7. Как учат ChatGPT.
Мы почти подобрались к концу, осталось понять, как учат ChatGPT.

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

К примеру возьмем необученную сеть и дадим ей продолжить фразу “Список страховых”:
Please open Telegram to view this post
VIEW IN TELEGRAM
Видим, что получившийся набор цифр и слово, которому он соответствует нам не подходят, так как обозначают слово “арбуз”.

Просим GPT пересчитать внутренние таблицы и снова даем начальную фразу:
Теперь получилось слово “компаний”. Нам подходит. Можем брать новую фразу и предлагать продолжить её. Разумеется, в реальности нейронка не обучится так быстро. Вначале она довольно долго будет выдавать билиберду, поэтому этот процесс будет происходить миллионы раз по каждому из примеров.

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

И вот тут у меня главная сложность. Для твердого объяснения того, почему результат о страховых компаниях получается неточным, мне бы нужны исходные данные, на которых тренировали 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