К предыдущему посту про разделение труда
В английском языке есть слово bangalored. «Отбангалорить» — значит уволить и перенести позицию в страну с более дешёвой рабочей силой. Этот термин возник в IT сфере США в 2000-х после лопнувшего пузыря доткомов. После кризиса многие компании сокращали расходы и отдавали работу на аутсорс в страны, где работникам можно платитьветку миску риса. Одним из центров притяжения новых рабочих мест стал город Бангалор на юге Индии.
Недавно Google уволила сотрудников из команд Flutter, Dart и Python. По словам бывшего сотрудника, замена была найдена в Мюнхене из-за более дешёвого найма. Кстати, советую почитать его тред. Интересно, как работники на западе реагируют на сокращения.
В 2022 году я грёб в аутсорс компании. Мы работали на проекте Fujitsu. После февральских событий, они решили прекратить сотрудничество с разработчиками из России и нашли нам замену в Бангалоре и Пуне. То есть, нас буквально отбангалорили😂 Как и сотрудники Google, мы проводили обучение тех, кто нас заменит. В том году я весь октябрь провёл в Индии, обучая свою замену. Фото, кстати, от туда.
К чему это всё и какой можно сделать вывод? Неважно, кто ты: работник MAANG-компании или гребец на галерах. Нужно быть готовым к тому, что бизнес решит тебя отбангалорить, поскольку это всегда происходит внезапно.
В английском языке есть слово bangalored. «Отбангалорить» — значит уволить и перенести позицию в страну с более дешёвой рабочей силой. Этот термин возник в IT сфере США в 2000-х после лопнувшего пузыря доткомов. После кризиса многие компании сокращали расходы и отдавали работу на аутсорс в страны, где работникам можно платить
Недавно Google уволила сотрудников из команд Flutter, Dart и Python. По словам бывшего сотрудника, замена была найдена в Мюнхене из-за более дешёвого найма. Кстати, советую почитать его тред. Интересно, как работники на западе реагируют на сокращения.
В 2022 году я грёб в аутсорс компании. Мы работали на проекте Fujitsu. После февральских событий, они решили прекратить сотрудничество с разработчиками из России и нашли нам замену в Бангалоре и Пуне. То есть, нас буквально отбангалорили
К чему это всё и какой можно сделать вывод? Неважно, кто ты: работник MAANG-компании или гребец на галерах. Нужно быть готовым к тому, что бизнес решит тебя отбангалорить, поскольку это всегда происходит внезапно.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
👆Продолжение поста
Сотрудники Google вряд ли будут испытывать проблемы с поиском работы. Но не у всех в резюме такая строчка, поэтому немного о том, как к этому можно подготовиться. Я вижу несколько вариантов (от простого к сложному):
1. Развивать навыки. В случае внезапного увольнения придётся конкурировать за рабочее место. Хорошо, если ты готов. Иначе придётся в очередной вспоминать, где хранятся классы и структуры, пока проедаешь финансовую подушку. Она ведь у тебя есть?
2. Развивать нетворкинг. Общаясь с другими специалистами, можно перенять их опыт, узнать о какой-то новой технологии. В случае проблем на работе можно объединить усилия и попытаться решить проблему максимально выгодным способом. На крайний случай, нетворкинг может помочь найти новую работу, если тебя зарефералят. Причём, не обязательно заводить знакомства только в офисе. Полезной может оказаться даже переписка в Telegram чате.
3. Договориться с работодателем. Например, о выходном пособии при сокращении. И не просто договориться, а закрепить договорённости на бумаге. Такая бумага называется коллективный договор. Конечно, сказать проще, чем сделать. Боюсь, многие даже не знают, что это такое.
Сотрудники Google вряд ли будут испытывать проблемы с поиском работы. Но не у всех в резюме такая строчка, поэтому немного о том, как к этому можно подготовиться. Я вижу несколько вариантов (от простого к сложному):
1. Развивать навыки. В случае внезапного увольнения придётся конкурировать за рабочее место. Хорошо, если ты готов. Иначе придётся в очередной вспоминать, где хранятся классы и структуры, пока проедаешь финансовую подушку. Она ведь у тебя есть?
2. Развивать нетворкинг. Общаясь с другими специалистами, можно перенять их опыт, узнать о какой-то новой технологии. В случае проблем на работе можно объединить усилия и попытаться решить проблему максимально выгодным способом. На крайний случай, нетворкинг может помочь найти новую работу, если тебя зарефералят. Причём, не обязательно заводить знакомства только в офисе. Полезной может оказаться даже переписка в Telegram чате.
3. Договориться с работодателем. Например, о выходном пособии при сокращении. И не просто договориться, а закрепить договорённости на бумаге. Такая бумага называется коллективный договор. Конечно, сказать проще, чем сделать. Боюсь, многие даже не знают, что это такое.
👍6
Уже 100 дней решаю проблемы на leetcode.
Изначально, я решал по 1 проблеме в день из LeetCode 75 и SQL 50. Задачи по SQL мне довольно быстро наскучили. Я на них забил и переключился на daily challenge.
Из ачивок на текущий момент есть:
1. Набор LeetCode 75.
2. Daily Challenges за апрель.
На самостоятельное решение некоторых проблем уровня Hard пока уходит неприлично много времени. В большинстве случаев я их решаю только после гугления. Но скилл нарабатывается и радует, что хоть какие-то сложные задачи могу решать самостоятельно.
Пока что тяжелее всего даётся:
- Greedy
- Dynamic Programming
- Bit Manipulation
Например, то, что нужно применить dynamic programming, я вижу практически мгновенно. Но как именно разбить задачу на подпроблемы, как связать решение подпроблем, как именно применить мемоизацию — пока даётся со скрипом.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2
В прошлое воскресенье на LeetCode в качестве челленджа была задачка Largest Local Values in a Matrix. Несмотря на уровень Easy, она демонстрирует важность последовательного доступа к данным.
Суть задачи
Дана матрица MxM. Нужно найти максимальные значения во всех матрицах 3x3, которые получаются из исходной матрицы. Решение от LeetCode реализовано так (рис. 1):
1. Берётся матрица 3x3.
2. Последовательно обходятся элементы матрицы в поисках максимума.
3. goto п.1.
Что не так с решением?
Например, что столбцы [9, 6, 2] и [8, 2, 6] относятся к матрицам 0 и 1, и будут обработаны несколько раз. Оптимальный алгоритм вернёт правильное решение, обработав каждый столбец и строку лишь 1 раз. Реализовать такой алгоритм можно 2 способами:
1. Обход по столбцам слева направо, сверху вниз (рис. 2).
2. Обход по строкам сверху вниз, слева направо.
Что быстрее? Кажется, что обход по столбцам. Да, но не всегда.
Причём тут последовательный доступ и кэш ЦПУ?
Реализация кэша ЦПУ основана на концепции локальности данных. При обращении к данным высока вероятность, что:
1. Вскоре к данным обратятся снова. Поэтому-то они и сохраняются в кэш.
2. Могут обратиться и к соседним данным. Поэтому кэширование происходит блоками определённого размера (cache line) и в кэш попадают не только запрашиваемые данные, но и соседние байты памяти.
В общем случае, если поведение программы не укладывается в концепцию выше, то производительность снижается. Например, для алгоритма с обходом по строкам, при размере матрицы 2000+ элементов, количество промахов кэша увеличивается многократно (рис. 3), что приводит к ухудшению производительности (рис. 4). Объясняется это непоследовательным доступом. В кэш попадают ненужные даные, ведь используется только 3 элемента из строки.
Но интересно то, что обход по строкам быстрее, если матрица небольшая (рис. 5). В таком случае, в кэш попадает практически вся матрица. А найти max значение 3-х элементов одной строки быстрее, чем 3-х элементов из разных строк.
Please open Telegram to view this post
VIEW IN TELEGRAM
⚡3❤🔥1
Недавно сербский портал N1 выпустил статью о самых высокооплачиваемых профессиях в Сербии. Как вы уже наверное догадались, больше всех зарабатывают в IT — средняя зарплата составляет 200 000 динар или 1707€. Диапазон колеблется от 587€ до 2143€, в зависимости от образования.
Вообще, в Сербии есть сайт HelloWorld, который похож на Хабр Карьеру. Там тоже вакансии, информация об IT-компаниях, отзывы и можно оставить данные о своей зарплате. Я сравнил доходы айтишников в Белграде и Москве на основе информации HelloWorld и Хабр Карьеры. На диаграммах значения после вычета налогов и без учёта премий.
Если смотреть по всем IT-специализациям, то зарплаты младших специалистов в Белграде выше или как минимум не хуже. А вот зарплаты опытных специалистов уступают на 13 – 20%.
Зарплаты разработчиков ПО тоже отличаются. В Белграде зарплаты интернов и джунов выше на 72% и 32% соответственно. Зарплаты мидлов и сеньоров ниже на 4% и 11%. Разница уже не такая большая.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3❤1
Очень короткий пост о том, как начать отслеживать покрытие кода тестами на примере MSTest.
1. Устанавливаем расширение Coverage Gutters для VS Code. Пользователи vim и neovim простите, сегодня пост не для вас.
2. Переходим в проект с тестами и добавляем библиотеку coverlet.msbuild.
dotnet add package coverlet.msbuild --version 6.0.2
3. Выполняем команду.
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura
4. Смотрим отчёт.
Calculating coverage result...
Generating report '..\coverage.cobertura.xml'
+-------------+------+--------+--------+
| Module | Line | Branch | Method |
+-------------+------+--------+--------+
| SomeProject | 100% | 100% | 100% |
+-------------+------+--------+--------+
+---------+------+--------+--------+
| | Line | Branch | Method |
+---------+------+--------+--------+
| Total | 100% | 100% | 100% |
+---------+------+--------+--------+
| Average | 100% | 100% | 100% |
+---------+------+--------+--------+
5. Жмём кнопку Watch в тулбаре VS Code (рис. 1) и изучаем покрытые и непокрытые участки кода. Они подсвечиваются зелёным и красным соответственно (рис. 2).
Поздравляю, вы великолепны!
При необходимости, результаты отчёта можно прикрутить в CI/CD в GitLab и отслеживать насколько хорошо покрыт тестами новый код из мердж реквестов (рис. 3).
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
Прокаченные params в C# 13
На днях Microsoft анонсировала новую версию C#. В ней есть фича, касающаяся
Ключевое слово
Но в новой версии C# можно использовать
В итоге, в теле метода
Но также стоит учесть, что использование
На днях Microsoft анонсировала новую версию C#. В ней есть фича, касающаяся
params. Если вы не в курсе, что это такое, то вот простой пример:public void SomeMethod() {
ArrayParams(1);
ArrayParams(1, 2, 3);
}
public void ArrayParams(params int[] values) {
// some work
}Ключевое слово
params – это синтаксический сахар, позволяющий вызывать метод ArrayParams с любым количеством параметров. Но за сахар надо платить, в данном случае – ненужными аллокациями. После компиляции в методе SomeMethod на каждый вызов ArrayParams создаётся экземпляр массива int[].public void SomeMethod() {
int[] array = new int[1]; // аллокация 1
array[0] = 1;
ArrayParams(array);
int[] array2 = new int[3]; // аллокация 2
RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
ArrayParams(array2);
}Но в новой версии C# можно использовать
Span<T> и ReadOnlySpan<T> вместо массива.public void SomeMethod() {
SpanParams(1);
SpanParams(1, 2, 3);
}
public void SpanParams(params ReadOnlySpan<int> values) {
// some work
}В итоге, в теле метода
SomeMethod аллокаций уже не будет. То есть, если вы любите писать высокопроизводительный код, то params вместе с ReadOnlySpan<T> — ваш бро.public void SomeMethod() {
SpanParams(RuntimeHelpers.CreateSpan<int>((RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/));
SpanParams(RuntimeHelpers.CreateSpan<int>((RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/));
}Но также стоит учесть, что использование
Span<T> накладывает ограничения – метод нельзя сделать асинхронным.// valid
public async Task ArrayParams(params int[] values) {
// some work
}
// error CS4012: Parameters or locals of type 'ReadOnlySpan<int>'
// cannot be declared in async methods or async lambda expressions.
public async Task SpanParams(params ReadOnlySpan<int> values) {
// some work
}
🆒6
Вопрос к C# разработчикам. В какой IDE вы больше всего пишете код на C#?
Final Results
48%
10%
42%
Пишет ли кто-нибудь, например, кастомные сниппеты кода, кроме меня? Я их создаю, когда замечаю, что пишу много boilerplate-кода. К примеру, для тестов у меня есть 4 сниппета:
- test-method (скрин 1);
- test-data-method;
- test-data;
- test-class.
Другой пример: часто добавляю required init-only свойства в классы кастомным сниппетом propreq (скрин 2). В самом популярном расширении для C# таких сниппетов нет (скрин 3).
Собственно, вопрос к тем, кто работает с Visual Studio и Rider: занимаетесь ли вы таким задротством или там уже всё «из коробки», и я зря страдаю?
P.S.
P.P.S.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🆒4
Начал готовить материал для новой статьи про производительность FrozenDictionary
Для тех, кто не в курсе, что такое FrozenDictionary, – это новая read-only generic-коллекция, которая появились в .NET 8. Его особенностью является улучшенная производительность на чтение, по сравнению с обычными коллекциями.
Что уже нашёл интересного:
1. FrozenDictionary – это абстрактный класс. Его конкретная реализация зависит от исходного словаря. Например, от типа ключа (значимый тип, string, int) или размера коллекции.
2. Некоторые реализации «замороженного» словаря вообще не содержат хэш-таблицы. Вместо этого для поиска значения используется линейный поиск через цикл for. Видимо, для некоторых случаев это быстрее, чем считать хэш.
3. Частое используется ключевое слово ref и агрессивный инлайн методов. Возвращение по ссылке позволяет избежать копирования значимых типов. А инлайн позволяет избежать оверхеда, связанного с вызовом методов.
В скором времени узнаем, насколько быстро всё это работает.
Для тех, кто не в курсе, что такое FrozenDictionary, – это новая read-only generic-коллекция, которая появились в .NET 8. Его особенностью является улучшенная производительность на чтение, по сравнению с обычными коллекциями.
Что уже нашёл интересного:
1. FrozenDictionary – это абстрактный класс. Его конкретная реализация зависит от исходного словаря. Например, от типа ключа (значимый тип, string, int) или размера коллекции.
2. Некоторые реализации «замороженного» словаря вообще не содержат хэш-таблицы. Вместо этого для поиска значения используется линейный поиск через цикл for. Видимо, для некоторых случаев это быстрее, чем считать хэш.
3. Частое используется ключевое слово ref и агрессивный инлайн методов. Возвращение по ссылке позволяет избежать копирования значимых типов. А инлайн позволяет избежать оверхеда, связанного с вызовом методов.
В скором времени узнаем, насколько быстро всё это работает.
🆒4