#dotnet #csharp #tip by Dave Callan
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🥳 Новый формат .NET-решения .slnx теперь доступен в последней превью-версии Rider
Этот формат находится в режиме превью в Visual Studio, а теперь еще и в Rider. Кажется, с новым форматом улучшена читаемость и возможность слияния (mergeability). Выше — пример различий по сравнению с существующим форматом для простого решения.
#dotnet #csharp #tip by Dave Callan
Этот формат находится в режиме превью в Visual Studio, а теперь еще и в Rider. Кажется, с новым форматом улучшена читаемость и возможность слияния (mergeability). Выше — пример различий по сравнению с существующим форматом для простого решения.
#dotnet #csharp #tip by Dave Callan
🎉46👍12🔥4❤1🤔1
По умолчанию он проверяет все правила и объединяет сообщения об ошибках. Более эффективно устанавливать
CascadeMode
либо на уровне класса, либо на уровне цепочки правил, особенно при использовании MustAsync
и асинхронных операций.#dotnet #csharp #tip by Saeed Esmaeelinejad
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18👍11🤔1👾1
🤔 Как можно аннотировать основной конструктор атрибутом?
Ранее, если у записи/класса/структуры было несколько конструкторов, возникала проблема с десериализацией, так как необходимо было указать атрибут
Начиная с C# 12, можно использовать method attribute target для указания конструктора☝️
#dotnet #csharp #tip by Oleg Kyrylchuk
Ранее, если у записи/класса/структуры было несколько конструкторов, возникала проблема с десериализацией, так как необходимо было указать атрибут
JsonConstructor
в основном конструкторе.Начиная с C# 12, можно использовать method attribute target для указания конструктора☝️
#dotnet #csharp #tip by Oleg Kyrylchuk
👍10🥰2
🔒🔥 В .NET 9 появится новый тип
Отличный вариант для выделенного типа
#dotnet #tip by Steven Giesel
Lock()
Отличный вариант для выделенного типа
lock
, поскольку это дает нам способ более четко выразить намерение нашего кода. #dotnet #tip by Steven Giesel
👍50🥱16❤1🔥1
💡 Parameter Object Pattern
Если метод принимает много связанных параметров, рассмотрите возможность группировки их в объект, чтобы упростить модификацию и сигнатуры.
Очень полезно, когда группа параметров часто используется повторно.
#dotnet #csharp #tip by Dave Callan
Если метод принимает много связанных параметров, рассмотрите возможность группировки их в объект, чтобы упростить модификацию и сигнатуры.
Очень полезно, когда группа параметров часто используется повторно.
#dotnet #csharp #tip by Dave Callan
😁23👍12🥱8👾3
🤔 Согласитесь, что глубоко вложенный код трудно читать?
В методах с большим количеством вложений можно использовать подход Early Return и Guard Clause, чтобы сделать код более удобным для чтения.
#dotnet #csharp #tip by Dave Callan
В методах с большим количеством вложений можно использовать подход Early Return и Guard Clause, чтобы сделать код более удобным для чтения.
#dotnet #csharp #tip by Dave Callan
👍44🥱35💯7🌚2
👆 Кстати, в EF 9 представлен новый удобный способ заполнения базы данных начальными данными.
#efcore #dotnet #tip by Nabi Karampour
#efcore #dotnet #tip by Nabi Karampour
👏39👍10🔥6🥰3
💡 Кстати,
Раньше приходилось перечислять каждый элемент complex типа в
#dotnet #efcore #tip by Oleg Kyrylchuk
ExecuteUpdate
поддерживает обновление complex типов в Entity Framework 9Раньше приходилось перечислять каждый элемент complex типа в
ExecuteUpdate
, а теперь он принимает complex тип, но вам все равно нужно указать каждый элемент.#dotnet #efcore #tip by Oleg Kyrylchuk
🔥18🤔1
🚀 Сравнение производительности конкатенации строк в .NET 9
Есть и другие подходы, когда нам нужна ещё более высокая производительность, но из распространённых подходов, показанных ниже,
#dotnet #csharp #tip by Dave Callan
Есть и другие подходы, когда нам нужна ещё более высокая производительность, но из распространённых подходов, показанных ниже,
StringJoin
выигрывает. #dotnet #csharp #tip by Dave Callan
👍25👏3👾2
Внутри SQL-движка соединение таблиц — это не магия, а конкретный алгоритм. Сравним два подхода к соединению таблиц.
Nested Loops работает буквально так, как звучит: берём строку из первой таблицы и ищем совпадения во второй. Если вторая таблица имеет подходящий индекс, поиск по нему будет очень быстрым, и такой алгоритм блестяще справляется с задачей маленькое соединяется с большим.
Hash Join подходит там, где Nested Loops захлёбывается. Он сначала строит хэш-таблицу по одной из входных таблиц, а затем пробегается по второй и ищет совпадения через хэш-функцию. Это даёт огромный выигрыш, когда нужно соединить два больших набора данных, и когда индексов для ускорения поиска нет. Цена такого подхода — расход памяти.
В итоге — если речь идёт о маленьком наборе строк против большого и есть индекс, Nested Loops окажется быстрее. Но если обе таблицы крупные и индексы не спасают, Hash Join чаще всего становится оптимальным выбором.
💬 Как вы бы ответили на такой вопрос на собеседовании?
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1
Пишите свои ответы в комментариях 👇
Для любознательных ответ такой:
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
🚩 Задача с собеса: пират и сундуки
Представьте, что вы пират и у вас есть 12 закрытых сундуков. Все они полны золотых монет, но один — фейковый: в нём только песок. Золото тяжелее, песок легче. У вас есть большие весы без гирь, и всего три взвешивания, чтобы вычислить пустышку.
Как решить эту задачу:
1.Делим сундуки на группы по 6 штук. Взвешиваем. Берём ту группу, где вес меньше.
2.Снова делим на группы, но теперь по 3. Взвешиваем. Берём ту тройку, где легче.
3. Сравниваем внутри этой тройки два сундука. Лёгкий сундук и будет с песком. Если сундуки одинаковые по весу, но с песком тот, что остался.
Задача решается бинарным поиском .
🐸 Библиотека шарписта
#dotnet_challenge
Представьте, что вы пират и у вас есть 12 закрытых сундуков. Все они полны золотых монет, но один — фейковый: в нём только песок. Золото тяжелее, песок легче. У вас есть большие весы без гирь, и всего три взвешивания, чтобы вычислить пустышку.
Как решить эту задачу:
1.
2.
3.
Задача решается
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23❤4👏4😁2
Есть код:
var dict = new Dictionary<object, string>();
dict[1] = "int";
dict[1L] = "long";
dict[1.0] = "double";
Console.WriteLine(dict.Count);
Console.WriteLine(dict[1 ]);
Что выведет код? Пишите в комменты 👇
Ответь спрячем здесь:
int
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🤔5❤2
🚩 Задача с собеса: контейнер с водой
Ваша задача — выбрать две вертикальные линии на плоскости, чтобы вместе с осью X они образовали контейнер, в который поместится максимум воды. Даны высоты этих линий в массиве.
Как действовать:
1. Ставим два указателя: один — на начало, второй — на конец массива.
2. Считаем объем текущего контейнера: ширина между указателями умножается на минимальную из двух высот.
3. Двигаем указатель с меньшей высотой внутрь. Если обе высоты равны — можно сдвигать любой.
4. Запоминаем максимум, повторяем шаги, пока указатели не встретятся.
По сути, это жадный алгоритм с двумя указателями, который перебирает края и минимизирует лишние проверки.
Пример реализации:
➡️ Попробовать на литкоде
🐸 Библиотека шарписта
#dotnet_challenge
Ваша задача — выбрать две вертикальные линии на плоскости, чтобы вместе с осью X они образовали контейнер, в который поместится максимум воды. Даны высоты этих линий в массиве.
Как действовать:
1. Ставим два указателя: один — на начало, второй — на конец массива.
2. Считаем объем текущего контейнера: ширина между указателями умножается на минимальную из двух высот.
3. Двигаем указатель с меньшей высотой внутрь. Если обе высоты равны — можно сдвигать любой.
4. Запоминаем максимум, повторяем шаги, пока указатели не встретятся.
По сути, это жадный алгоритм с двумя указателями, который перебирает края и минимизирует лишние проверки.
Пример реализации:
public int MaxArea(int[] h)
{
int l = 0, r = h.Length - 1, m = 0;
while (l < r)
{
m = Math.Max(m, (r - l) * Math.Min(h[l], h[r]));
if (h[l] < h[r]) l++; else r--;
}
return m;
}
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤2
Вам дан отсортированный по возрастанию массив целых чисел. Нужно создать новый массив, в котором содержатся квадраты этих чисел — и он тоже должен быть отсортирован по возрастанию.
Поскольку исходный массив отсортирован, отрицательные числа после возведения в квадрат могут стать больше положительных, поэтому нужно рассматривать оба края массива.
1. Обрабатываем два края массива (left и right), сравниваем их квадраты.
2. Наибольший квадрат записываем в конец результирующего массива.
3. Сдвигаем соответствующий указатель — либо left, либо right.
4. В конце получаем отсортированный массив квадратов.
Решение с двумя указателями:
public int[] SortedSquares(int[] nums) {
int n = nums.Length;
int[] result = new int[n];
int left = 0, right = n - 1, pos = n - 1;
while (left <= right) {
int leftSq = nums[left] * nums[left];
int rightSq = nums[right] * nums[right];
if (leftSq > rightSq) {
result[pos] = leftSq;
left++;
} else {
result[pos] = rightSq;
right--;
}
pos--;
}
return result;
}
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7❤🔥6🥱2
Задача: дана строка
s
и строка p
. Необходимо найти все начальные индексы подстрок в s
, которые являются анаграммами строки p
.Анаграмма — это слово или фраза, образованная перестановкой букв другого слова, используя все исходные буквы ровно один раз.
Пример:
Input: s = "cbaebabacd", p = "abc"
Output: [0, 6]
Объяснение:
Подстрока с индекса 0 - "cba", анаграмма "abc".
Подстрока с индекса 6 - "bac", анаграмма "abc".
Оптимальное решение использует технику скользящего окна с подсчетом частот символов.
1. Подсчитываем количество и частоту всех символов в строке p
2. Создаем скользящее окно размером со строку
p
в строке s
3. Для каждой позиции окна сравниваем частоты символов с эталоном
4. При совпадении добавляем индекс в результат
Код:
public class Solution
{
public IList<int> FindAnagrams(string s, string p)
{
List<int> result = new List<int>();
if (s.Length < p.Length)
return result;
// Массивы для подсчета частот символов (26 букв английского алфавита)
int[] pCount = new int[26];
int[] windowCount = new int[26];
// Подсчитываем частоты в строке p и первом окне
for (int i = 0; i < p.Length; i++)
{
pCount[p[i] - 'a']++;
windowCount[s[i] - 'a']++;
}
// Проверяем первое окно
if (AreEqual(pCount, windowCount))
result.Add(0);
// Скользим окном по строке s
for (int i = p.Length; i < s.Length; i++)
{
// Добавляем новый символ справа
windowCount[s[i] - 'a']++;
// Удаляем старый символ слева
windowCount[s[i - p.Length] - 'a']--;
// Проверяем текущее окно
if (AreEqual(pCount, windowCount))
result.Add(i - p.Length + 1);
}
return result;
}
// Вспомогательный метод для сравнения массивов частот
private bool AreEqual(int[] arr1, int[] arr2)
{
for (int i = 0; i < 26; i++)
{
if (arr1[i] != arr2[i])
return false;
}
return true;
}
}
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩3❤2🔥2💯2👾2
🔄 Как развернуть связный список
Дан связный список, нужно развернуть его задом наперёд. Разберём как решить задачу элегантно.
У вас есть цепочка узлов: 1 → 2 → 3 → 4 → 5. Каждый узел хранит значение и ссылку на следующий элемент. Задача — перевернуть все стрелки: 1 ← 2 ← 3 ← 4 ← 5.
Главная сложность здесь не в алгоритме, а в работе с указателями. Стоит перезаписать ссылку неправильно — и вы теряете доступ к остальной части списка. Именно поэтому многие решения проваливаются на первой попытке.
Итеративное решение: три указателя
Самый надёжный подход — использовать три указателя, которые двигаются по списку синхронно.
• prev отслеживает предыдущий узел
• curr указывает на текущий обрабатываемый узел
• next сохраняет следующий узел, чтобы не потерять его при развороте
Код:
Рекурсивное решение
Если вам нравятся рекурсивные решения, есть и такой вариант:
Попробуйте решить задачу сами, прежде чем смотреть готовый код. Нарисуйте список на бумаге, отследите движение указателей вручную. Это единственный способ понять, что происходит.
➡️ Решить задачу
🐸 Библиотека шарписта
#dotnet_challenge
Дан связный список, нужно развернуть его задом наперёд. Разберём как решить задачу элегантно.
У вас есть цепочка узлов: 1 → 2 → 3 → 4 → 5. Каждый узел хранит значение и ссылку на следующий элемент. Задача — перевернуть все стрелки: 1 ← 2 ← 3 ← 4 ← 5.
Главная сложность здесь не в алгоритме, а в работе с указателями. Стоит перезаписать ссылку неправильно — и вы теряете доступ к остальной части списка. Именно поэтому многие решения проваливаются на первой попытке.
Итеративное решение: три указателя
Самый надёжный подход — использовать три указателя, которые двигаются по списку синхронно.
• prev отслеживает предыдущий узел
• curr указывает на текущий обрабатываемый узел
• next сохраняет следующий узел, чтобы не потерять его при развороте
Код:
public ListNode ReverseList(ListNode head)
{
ListNode prev = null;
ListNode curr = head;
while (curr != null)
{
ListNode next = curr.next; // сохраняем следующий
curr.next = prev; // разворачиваем стрелку
prev = curr; // двигаем prev
curr = next; // двигаем curr
}
return prev;
}
Рекурсивное решение
Если вам нравятся рекурсивные решения, есть и такой вариант:
public ListNode ReverseList(ListNode head)
{
if (head == null || head.next == null)
return head;
ListNode newHead = ReverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
Попробуйте решить задачу сами, прежде чем смотреть готовый код. Нарисуйте список на бумаге, отследите движение указателей вручную. Это единственный способ понять, что происходит.
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🙏2👾1
Дан массив цен акций по дням. Нужно найти максимальную прибыль, совершая любое количество сделок купли-продажи. Одновременно можно держать только одну акцию.
Пример:
Цены: [7, 1, 5, 3, 6, 4]
Ответ: 7
Покупаем за 1, продаём за 5 (прибыль 4). Покупаем за 3, продаём за 6 (прибыль 3). Итого — 7.
Алгоритм
Самый простой подход — жадный алгоритм. Если завтра цена выше, чем сегодня — покупаем сегодня и продаём завтра. Собираем прибыль с каждого роста цены.
Представьте график цен: вам нужно получить прибыль со всех участков, где график идёт вверх. Неважно, сколько это будет сделок — каждый рост приносит деньги.
Почему это работает
Если цена растёт три дня подряд (например, 1 → 3 → 5), то неважно, продавать ли каждый день или держать до конца.
Код:
public class Solution
{
public int MaxProfit(int[] prices)
{
if (prices == null || prices.Length < 2)
return 0;
int totalProfit = 0;
for (int i = 1; i < prices.Length; i++)
{
// Если цена выросла — берём эту прибыль
if (prices[i] > prices[i - 1])
{
totalProfit += prices[i] - prices[i - 1];
}
}
return totalProfit;
}
}
Или ещё компактнее:
public class Solution
{
public int MaxProfit(int[] prices)
{
int profit = 0;
for (int i = 1; i < prices.Length; i++)
{
profit += Math.Max(0, prices[i] - prices[i - 1]);
}
return profit;
}
}
Жадный подход здесь безупречен: захватываем каждый рост, игнорируем падения. Никаких сложных расчётов оптимальных точек — только простая логика и максимальная прибыль.
Чтобы щёлкать такие задачи нужно знать алгоритмы. Подтянуть такую базу поможет наш курс по алгоритмам. До конца октября скидка 40%
#dotnet_challenge
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4👍1