Эшу быдлокодит
298 subscribers
128 photos
12 videos
7 files
169 links
Дневник C# разработчика.

Личка: @EshuMarabo
Гитхаб: https://github.com/vladzvx

Стек: C#, PostgreSQL
Download Telegram
В прошлом году итоги я подвёл в ноябре при запуске #палантир@eshu_coding, после него ничего особо интересного не было.

В этом году никаких проектов не под NDA, я в общем-то не делал. Если без подробностей, то вот краткие итоги личностного роста:
1. Научился готовить Tarantool, прошёлся по куче граблей, примерно понял, где он реально нужен, и главное, где не нужен. Пришлось поверхностно познакомиться и с механизмом построения кластеров: репликация, шардирование, вот это вот всё.

2. Нырнул в MongoDB на уровне, отличном от "положил как в помойку, достал по id/однострочному запросу". Многоступенчатые запросы, подписки на обновления коллекций, TTL, транзакции, materialised view. Впервые завел реплика-сет вместо отдельностоящего инстанса.

3. Построил пару обменников на RabbitMQ, пришло осознание проглоченного и применённого на коленке в 2021.

4. Влюбился в систему сбора метрик Prometheus. Если раскидать их по приложению и заодно подключить сбор с компонентов системы (баз данных и т.д.), получается крайне информативно. Дефолтный визуализатор так себе, но основные функции выполняет.

5. Познакомился с EKL стеком - сбор и визуализация логов. Особой любви не случилось, уж больно оно огромно и прожорливо. Можно кстати использовать ELK для построения красивых дашбордов по данным из Prometheus-а, но это мне пока не особо нужно.

6. Прогресс как шарписта у меня вышел так себе. Научился красиво описывать rest api с помощью Swagger, да в общем-то и всё. Ну ещё окончательно освоил разработку с использованием докера: приложение сразу запускается и отлаживается в контейнере, окружённое соседними сервисами. При прогоне тестов также активно использую песочницу, поднятую в docker-compose.

P.S. NoSQL я накушался досыта, 2023 - время вернуться к истокам - C# + PostgreSQL.
👍91
Ну чтож, надо посмешить богов, озвучить свои планы.

Чего хочу я в этом году:
1. Немного обмазаться фронтенд разработкой, но без фанатизма. Пока думаю о связке React + Typescript.

2. Попробовать на практике стандартную шарповую ORM: Entity Framework.

3. Углубиться в PostgreSQL, поиграться с уровнями изоляции транзакций, подтянуть оптимизацию запросов, возможно попробовать пособирать разные конфигурации кластеров на foreign table.

4. Прочитать несколько умных книжек, что-то типа:
a) Рихтер
b) Высоконагруженные приложения Фаулера
c) Ещё что-нибудь по архитектуре.

5. Начать подтягивать базу по Computer Science, мб копнуть алго задачи.

Вот такие планы, интересно, что исполнится к концу года:)
🔥7👍4👏2
Эшу быдлокодит
Ну чтож, надо посмешить богов, озвучить свои планы. Чего хочу я в этом году: 1. Немного обмазаться фронтенд разработкой, но без фанатизма. Пока думаю о связке React + Typescript. 2. Попробовать на практике стандартную шарповую ORM: Entity Framework. 3.…
Ну что же, фронтенд мой пока закончился на попытке нормально подружить Visual Studio и фронтенд разработку.

Я стремительно расширяю сознание в части строительства всякого интересного на базе MongoDB, скоро буду выходить на новый уровень в части работы с RabbitMQ.

PostgreSQL? Entity Framework? Фронтенд? Планирование? Не, это для лохов.
🔥3🤡2🤔1
Не прошло и 5 лет работы с с#, как я сподобился начать читать в режиме "от корки до корки" базовую книгу: Рихтера. Она несколько устарела: относится к версии языка от 2012 года. Но т.к. базовые концепции, лежащие в основе, с тех пор не поменялись, так что ознакомиться надо.

В начале (введение, общий обзор механики CLR, сборки проектов) ничего нового толком не было, я либо все знал, либо оно было мне уже не актуально. Но стоило дойти до конкретики - некоторые моменты, используемые мной годами, стали вставать на свои места.

Так, операцию сравнения - == между двумя экземплярами класса надо применять с осторожностью, результат зависит далеко не только от их содержимого.

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

Во всех экземплярах классов хранится ссылка на объект-тип. GetType как раз ее и возвращает. Не то, чтобы что-то революционное, просто небольшой штрих в общей картине.

Далее здесь будет что-то типа конспекта, который буду писать по мере прочтения. Ну и будут новые теги:
#книги
#Рихтер
👍2
Практически осилил фундаментальную главу про типы. В целом - почти ничего нового, но пару занятных нюансов вычитал.

В с# есть разделение на типы - значимые (структуры, живут обычно в стеке) и ссылочные (обычные классы, живут в куче).

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

Обычная практика - сделать структуру вида "координата", содержащую х, у и z и пользоваться ей.

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

Ещё из интересного - если выдавливать максимум производительности, то использовать штатные методы -ToString, GetType, GetHashCode для значимых типов стоит с осторожностью - легко наступить на грабли и засрать кучу мусором - во многих случаях сначала будет произведена операция упаковки (сама по себе не очень быстрая) значимого типа в кучу из стека, а потом уже вызван метод. Те из них, которые поддаются переопределению - переопределить. А GetType - использовать только по большой нужде. Кроме траты времени на упаковку мы нагружаем сборщик мусора, что в некоторых случаях даже печальнее.

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

#книги
#рихтер
👍3
Сколько времени программисту нужно, чтобы разобраться с тем, как включить мультики с usb с телевизора?

15 минут и помощь системного аналитика, знающего бэкдор: направлять пульт строго в правый нижний угол телевизора.
😁5
Эшу быдлокодит
Практически осилил фундаментальную главу про типы. В целом - почти ничего нового, но пару занятных нюансов вычитал. В с# есть разделение на типы - значимые (структуры, живут обычно в стеке) и ссылочные (обычные классы, живут в куче). Для значимых сравнение…
Продолжаю читать про типы. Наткнулся на пару моментов, где я по незнанию лепил избыточный код:
1. Увидел как вызывать конструктор из другого конструктора. Чуть меньше копипасты:)
2. Узнал, что статический конструктор по умолчанию потокобезопасен. То есть все мои неэстетичные огородики с блокировками в таких конструкторах отправляются на помойку. Отлично.

#рихтер
#книги
👍4
Наткнулся на забавный вопрос к собеседованиям:

Как изменить в уже запущенной программе значение строковой константы?

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

В c# есть особый раздел языка: unsafe. По сути, это что-то вроде урезанного языка c++. И вот с помощью такой вставки можно получить указатель на место в памяти, где хранится эта константа и нагадить записать туда свои байтики.

Потому родился встречный вопрос:
А у вас в кодовой базе такое практикуется?
🔥6
Forwarded from javawatch
ChatGPT достигла уровня человека! Я попросил ее написать пример использования модулей в C++23 через cmake, и у нее не получилось. У меня тоже не получилось. Каких высот мы достигли!
😁6🤡1
Познакомился с работой с координатами на карте. Широта и долгота, x и y, логично ведь? Север на карте - сверху, вертикаль - это y. А горизонталь - x.

А вот стандартная шарповая библиотека для работы с пространством считает иначе, придется с этим жить.

#csharp
А монга своей простотой однако развращает. После года плотной работы с ней, почти в любой ситуации, когда надо какое-то хранение состояния хочется просто насрать им записать его в монгу и пойти дальше.
На неделе надо было максимально быстро накидать незамысловатый UI для внутреннего пользования, так чтобы работало на Винде, посмотрел несколько вариантов реализации:
1. C# Win Forms
2. C# WPF.
3. C# MAUI
4. React.js

У Win Forms в наличии визуальный редактор: накидал элементов, сгенерировался c# код, чуть поправил его под себя - и готово.

У WPF - тоже есть редактор, но генерируется xaml разметка, что-то типа xml. Главная проблема, что его тоже нужно знать.

MAUI - тот же xaml. Не предполагает визуального редактора. Предлагаемый путь разработки - пересборка приложения на ходу, на живую: приложение запущено в дебаге, ты на ходу правишь xaml и смотришь результат. Заманчивой выглядит перспектива кроссплатформенности: одна и та же кодовая база собирается под Android, iOS и Windows. Главный недостаток MAUI - низкая распространенность. Изучать его имеет смысл если только для души.

React - это другой язык программирования - Java Script. Может быть собран в приложение под любую распространенную ОС, но основная точка приложения - веб сайты. Разработка идёт примерно как в MAUI: открыт браузер, меняется код - меняется внешний вид сайта.

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

В итоге я зажал нос и решил свою задачу на Win Forms за несколько часов, после чего пошел дальше. Но с реактом я когда-нибудь разберусь!
👍4😁3
Есть такой продукт для обмена данными между микросервисами - RabbitMQ, я его неоднократно упоминал в канале выше. Это - брокер сообщений, вся суть его - передача информации из входной точки (обменника) к выходным (очереди), на которые подписываются сервисы. RabbitMQ поддерживает гарантированную доставку сообщения. Даже если рухнет мироздание вся инфраструктура, когда она оживет - брокер может поднять помещенные в него сообщения и продолжить передавать их подписчикам.

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

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

Оказалось, что настройка "не удалять очередь при рестарте RabbitMQ" вообще ниразу не значит, что надо сохранять все помещенные в нее сообщения. Удаление сообщения регулируется отдельно, при том в момент публикации можно выбрать настройку персистентентности для каждого сообщения в отдельности.

RabbitMQ позволяет принимать сообщения как синхронно, так и асинхронно. Для обоих способов предусмотрены специальные методы. Но вот беда - асинхронный прием сообщений не работает. Оказалось, сообщать RabbitMQ что я буду принимать асинхронные оповещения надо на этапе подключения к нему.

В остальном RabbitMQ прекрасен: удобно и быстро настраивается из с#, нагрузку держит.

#rabbitmq
👍3
Наткнулся на неочевидную проблему при приеме данных от RabbitMQ. Когда блямкает оповещение, оно представляется неким классом, имеющим поле типа ReadonlyMemorySpan<byte>, то есть по большому счету ссылка на область памяти с указанием размера.

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

Сделал копирование байтиков в массив сразу по получении - и проблема рассосалась.

#rabbitmq
😁1
Эшу быдлокодит
На неделе надо было максимально быстро накидать незамысловатый UI для внутреннего пользования, так чтобы работало на Винде, посмотрел несколько вариантов реализации: 1. C# Win Forms 2. C# WPF. 3. C# MAUI 4. React.js У Win Forms в наличии визуальный редактор:…
У меня таки дошли руки до раскуривания реакта, ещё немного и я смогу быть junior react developer!

В несколько подходов отработал основные концепции:
1. Хранение состояний, композиция хранилищ, перерисовка компонента при изменение состояния, относящегося к ней (например - таблицы при появлении новых данных).
2. Роутинг внутри сайта: переходы между логин-экран1-экран-2 и так далее.
3. Адаптивная верстка: на мобилке - один ui, в браузере - другой.
4. Потыкал самые распространенные компоненты, типа текстового ввода.
5. Разобрался с разметкой страниц (ни капли html, что характерно).
6. Научился принимать и отправлять данные как обычными запросами, так и веб советами.

В общем, можно начинать творить:)

#react #кодинг #js
До недавнего времени из-за ограничений браузера для организации постоянной связи браузер-бэкенд надо было или использовать веб-сокеты и гонять через них json-ы, или использовать web-gRPC, прибавляя дополнительный узел прокси сервера на бэке, роль которого сводилась к конвертации порезанного под браузер протокола в вид, понятный человеческому gRPC.

И тут совершенно случайно узнал, что в c# совсем недавно завезли поддержку браузерной gRPC. Осталось протестировать и насадить практику использования этого чуда инженерной мысли на фронте.
👍1
Оказалось довольно удобно совмещать ORM с хранением jsonb в постгресе. Делаешь модельку вида:

class Model
{
Int Field1,
String Field2,
String Field3,
InnerModel ClassField
}

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

А остальные поля, которые надо будет только читать, в т.ч. содержащие подклассы и массивы, уезжают в поле, содержащее класс (ClassField в примере). Помечяешь поле атрибутом "хранить как jsonb" и ORM сама сериализует и десериализует его. В итоге, вместо веера из десятка таблиц, разложенных по нормальным формам, получаем одну, время чтения и модификации данных соответственно уменьшается.

Итого, лёгким движением руки Postgres превращается, Postgres превращается...
в мутанта, содержащего признаки реляционки и монги.

/Напевает себе под нос/ Денормализация! Денормализация!

#postgresql
😁3
Существует целая куча брокеров сообщений и того, что может быть использовано в их качестве. Kafka, RabbitMQ, ActiveMQ, NATS. Продукты от AWS, Microsoft Azure, Yandex Cloud. Notify в PostgreSQL, Queue в Тарантуле, очередь в Redis и ещё куча других решений.

При выборе брокера сообщений я бы задал один вопрос:

Вам понадобится практически неограниченное горизонтальное масштабирование, чтобы можно было сдерживать нелинейный рост нагрузки, превышающей ~10 тыс сообщений в секунду? А если ещё раз подумать?

Если да - то ваш путь лежит в мир боли Кафку и экосистему Apache, практически без вариантов. Возможно, облачные поделия и не уступят ей, но это не точно, да и в 2023 в России уже не особо актуально.

Если планируемый рост нагрузки не столь страшен - отталкиваться можно от используемого стека. Все живёт в Azure? Берём их брокер. У нас целый зверинец продуктов Apache? Можно ActiveMQ или простенькую конфигураци Kafka. Пишем на Go? NATS отлично впишется в качестве подключаемого модуля, прямо внутрь вашего приложения, правда он не умеет сохранять опубликованные в нем сообщения после падения.

Ну а если нет какой-то такой специфики - берём попсовый RabbitMQ, знакомый практически каждому бэкенд разработчику, и не выпендриваемся.
👍2
Forwarded from Sandbox
Я пытался трудоустроится джуном в мск, я использовал площадку hh. И не использовал другие площадки (просто потому что мне было лень). По правилам своего эксперимента у меня было законченное высшее и не было никакого опыта работы.

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


И того, изначально я составил простенькое резюме в которое я упихал свое ФИО и указал универ. т.к. более ничего у меня не было. С таким резюме я вышел на рынок и отправил 30 откликов отклики отправлялись на: стажировки, поиски разработчика, поиски разработчика без опыта, поиски джуниора, поиск разработчика с опытом 1-3. Так же дополнительно при отклике я прикладывал сопроводительное письмо, которое мне сгенерировал ИИ.

Из этих 30 откликов я получил 4 предложения пройти тестовое. Рассмотрев все 4, я решил что меня заинтересует только 1. (К нему мы еще вернемся).

Следующим шагом был большой спор в одном из чатов по результатам которого в резюме добавилось следующее: Фотография, ссылка на гитхаб с проектами, подробное описание технических книг, а так же в опыт было вписаны курсовые и дипломные работы. (Важно отметить, что я не врал и честно указал, что это именно курсовые и дипломные работы). С таким подходом я получил 3 года опыта. С новым резюме я отправил еще 30 откликов. Здесь все пошло куда живее, на каждый 3й отзыв я получал приглашение пройти тестовое задание.

И того я имел на руках 14 приглашений на 60 откликов.
Мной было выполнено 10 тестовых из которых я получил ответ на 4. Очень часто за тестовым заданием шло еще одно таким образом фильтр сузился до 2х собеседований.

На каждом из собеседований прогнали по основам языка, паттернам и немного sql, по итогам собеседований было получено 2 приглашения присоединиться к рабочим командам с примерной зарплатой в 50к рублей.

Важные замечания. Не нужно врать, но опыт должен быть заполнен. Вас никто не позовет на собес, без тестового, вы сделаете очень много работы в стол. Если не отчаиваться - то точно получится. Если вы тупы как пробка, будет сложно, возможно стоит еще поучиться.

На весь эксперимент было потрачено около 3х недель. Итогов к сожалению не будет, т.к. принять предложения я не успел, да и не собирался.
👍3👏3