ru
Feedback
C# | Вопросы собесов

C# | Вопросы собесов

Открыть в Telegram
5 048
Подписчики
-124 часа
-177 дней
-2630 день
Архив постов
🤔 С точки зрения контроля версий, каким образом обмениваться изменениями в базе данных?
Anonymous voting

💸 Вакансии для IT'шников Выбери своё направление ⤵ 1. Frontend 2. Python 3. Java 4. Тестировщик QA 5. Data Science 6. DevOps 7. C# 8. С/C++ 9. Golang 10. PHP 11. Kotlin 12. Swift

📌 В чем отличие монолитной и микросервисной архитектуре на практике? 💬 Спрашивают в 11% собеседований Монолитная и микросервисная архитектуры представляют собой два разных подхода к построению программных систем. Рассмотрим ключевые отличия между ними на практике: 🤔 Монолитная архитектура Определение: Монолитная архитектура представляет собой единое, цельное приложение, в котором все компоненты и модули тесно связаны друг с другом. Особенности: 1️⃣ Единый код: ➕ Вся логика и функциональность приложения собраны в одном проекте или исполняемом файле. ➕ Пример: Веб-приложение, где UI, бизнес-логика и доступ к данным находятся в одном проекте. 2️⃣ Разработка и деплой: ➕ Разработка может быть проще на начальном этапе, так как все компоненты находятся в одном проекте. ➕ Деплой представляет собой единое целое: обновление требует полного перезапуска приложения. 3️⃣ Тестирование: ➕ Процесс тестирования проще, так как все находится в одном проекте. ➕ Тесты могут покрывать весь функционал приложения сразу. 4️⃣ Масштабирование: ➕ Масштабирование происходит путем клонирования всего приложения (вертикальное масштабирование). ➕ Ограничено возможностями одного сервера. 5️⃣ Связность: ➕ Высокая степень связности между компонентами может привести к трудностям в поддержке и модификации. ➕ Изменение одного компонента может потребовать пересмотра всего приложения. 🤔 Микросервисная архитектура Определение: Микросервисная архитектура разделяет приложение на множество небольших, независимых сервисов, каждый из которых выполняет свою конкретную задачу. Особенности: 1️⃣ Разделение кода: ➕ Логика приложения разделена на отдельные сервисы, каждый из которых может разрабатываться, тестироваться и деплоиться независимо. ➕ Пример: Интернет-магазин с отдельными сервисами для управления товарами, заказами, платежами и пользователями. 2️⃣ Разработка и деплой: ➕ Разработка может быть сложнее из-за необходимости координации между командами. ➕ Деплой каждого сервиса может выполняться независимо, что позволяет обновлять части системы без перезапуска всего приложения. 3️⃣ Тестирование: ➕ Тестирование может быть сложнее, так как необходимо тестировать взаимодействие между сервисами. ➕ Поддержка контрактного тестирования и других методологий для обеспечения совместимости сервисов. 4️⃣ Масштабирование: ➕ Масштабирование происходит горизонтально: можно масштабировать только те сервисы, которые испытывают высокую нагрузку. ➕ Более гибкое и эффективное использование ресурсов. 5️⃣ Связность: ➕ Сервисы слабо связаны друг с другом, что облегчает их поддержку и модификацию. ➕ Изменение одного сервиса не требует изменения других, что уменьшает риск. 🤔 Пример на практике Монолит: Предположим, у вас есть интернет-магазин. В монолитной архитектуре все функции, такие как каталог товаров, корзина, заказы, учетные записи пользователей и платежи, находятся в одном приложении. Обновление логики корзины требует развертывания всего приложения заново. Микросервисы: В микросервисной архитектуре каждый компонент интернет-магазина становится отдельным сервисом. Есть отдельные сервисы для каталога товаров, корзины, заказов, учетных записей пользователей и платежей. Если нужно обновить логику корзины, вы можете развернуть только соответствующий сервис, не затрагивая остальные. 🤔 Краткий ответ Монолитная архитектура объединяет все компоненты приложения в одном проекте, что упрощает разработку и деплой, но усложняет масштабирование и поддержку. Микросервисная архитектура разделяет приложение на независимые сервисы, что улучшает масштабируемость и модульность, но усложняет координацию и тестирование. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

🤔 Как можно хранить типы данных без unboxing?
Anonymous voting

📌 Какие есть паттерны проектирования? 💬 Спрашивают в 11% собеседований Паттерны проектирования — это шаблоны для решения общих проблем при разработке ПО. Они делятся на три категории: 🤔 Порождающие (Creational)Singleton: Один экземпляр класса. ➕ Factory Method: Создание объектов через методы. ➕ Abstract Factory: Семейства связанных объектов. ➕ Builder: Пошаговое создание сложных объектов. ➕ Prototype: Клонирование объектов. 🤔 Структурные (Structural)Adapter: Преобразование интерфейсов. ➕ Bridge: Разделение абстракции и реализации. ➕ Composite: Деревья объектов. ➕ Decorator: Добавление поведения объектам. ➕ Facade: Упрощение интерфейсов. ➕ Flyweight: Разделение мелких объектов. ➕ Proxy: Заместитель объектов. 🤔 Поведенческие (Behavioral)Observer: Оповещение об изменениях. ➕ Strategy: Замена алгоритмов. ➕ Command: Инкапсуляция запросов. ➕ Iterator: Последовательный доступ. ➕ Mediator: Посредник для взаимодействия. ➕ State: Смена поведения в зависимости от состояния. ➕ Chain of Responsibility: Цепочка обработчиков. ➕ Visitor: Добавление операций к объектам. ➕ Template Method: Скелет алгоритма. 🤔 Краткий ответ Паттерны проектирования (порождающие, структурные, поведенческие) — это шаблоны для решения типовых задач в разработке ПО, улучшающие структуру и гибкость кода. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

🤔 Какие встроенные типы делегатов существуют в C#?
Anonymous voting

📌 Что такое паттерны проектирования? 💬 Спрашивают в 11% собеседований Паттерны проектирования (или шаблоны проектирования) — это проверенные решения общих проблем, которые возникают при разработке программного обеспечения. Они представляют собой шаблоны для организации кода, которые улучшают его структуру, читаемость и повторное использование. Паттерны проектирования не являются готовым кодом, но они предлагают структуры и подходы, которые можно адаптировать к конкретным потребностям проекта. 🤔 Основные категории паттернов проектирования 1️⃣ Порождающие паттерны (Creational Patterns): Эти паттерны связаны с созданием объектов, что позволяет скрыть сложность создания объектов и повысить гибкость системы. ➕ Примеры: Singleton, Factory Method, Abstract Factory, Builder, Prototype. 2️⃣ Структурные паттерны (Structural Patterns): Эти паттерны описывают, как классы и объекты могут быть объединены для формирования больших структур. ➕ Примеры: Adapter, Composite, Proxy, Flyweight, Facade, Bridge, Decorator. 🤔 Примеры паттернов проектирования 🤔 Singleton (Порождающий паттерн) Обеспечивает создание единственного экземпляра класса и предоставляет глобальную точку доступа к этому экземпляру.
public class Singleton
{
    private static Singleton instance;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}
🤔 Factory Method (Порождающий паттерн) Определяет интерфейс для создания объекта, но позволяет подклассам изменить тип создаваемого объекта.
public abstract class Product { }

public class ConcreteProductA : Product { }

public class ConcreteProductB : Product { }

public abstract class Creator
{
    public abstract Product FactoryMethod();
}

public class ConcreteCreatorA : Creator
{
    public override Product FactoryMethod()
    {
        return new ConcreteProductA();
    }
}

public class ConcreteCreatorB : Creator
{
    public override Product FactoryMethod()
    {
        return new ConcreteProductB();
    }
}
🤔 Adapter (Структурный паттерн) Позволяет объектам с несовместимыми интерфейсами работать вместе.
public interface ITarget
{
    void Request();
}

public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Specific request");
    }
}

public class Adapter : ITarget
{
    private readonly Adaptee _adaptee;

    public Adapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }

    public void Request()
    {
        _adaptee.SpecificRequest();
    }
}
🤔 Observer (Поведенческий паттерн) Определяет зависимость "один ко многим" между объектами таким образом, что при изменении состояния одного объекта все зависимые объекты оповещаются и обновляются автоматически.
public interface IObserver
{
    void Update();
}

public class ConcreteObserver : IObserver
{
    public void Update()
    {
        Console.WriteLine("Observer updated");
    }
}

public class Subject
{
    private readonly List<IObserver> observers = new List<IObserver>();

    public void Attach(IObserver observer)
    {
        observers.Add(observer);
    }

    public void Detach(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (var observer in observers)
        {
            observer.Update();
        }
    }
}
🤔 Краткий ответ Паттерны проектирования — это проверенные решения общих проблем в разработке программного обеспечения. Они делятся на три категории: порождающие (Singleton, Factory Method), структурные (Adapter, Composite) и поведенческие (Observer, Strategy). Использование паттернов улучшает структуру кода, делает его более читаемым и гибким. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

😒 На одном кодинге уже давно не вывезешь, перспектива 2024 года - Информационная Безопасность Ловите два канала на тему ИБ и
😒 На одном кодинге уже давно не вывезешь, перспектива 2024 года - Информационная Безопасность Ловите два канала на тему ИБ и хакинга ZeroDay - Уроки по кибербезопасности и хакингу с нуля. Вирусы, взломы, OSINT, криптография и свежие новости Белый Хакер - программное обеспечение, утилиты, OSINT, инструменты, полезная литература и много другое. Совершенно новый формат непохожий на другие каналы.

Сообщество IT-специалистов в Telegram от Selectel. Канал крупнейшего независимого провайдера IT-инфраструктуры и облаков. Шес
Сообщество IT-специалистов в Telegram от Selectel. Канал крупнейшего независимого провайдера IT-инфраструктуры и облаков. Шесть причин подписаться на канал: - железные новости; - обзоры продуктов; - разборы кейсов; - актуальные IT-статьи; - анонсы митапов; - бесплатные курсы. Подписаться #реклама О рекламодателе

🤔 Как работает join в C#?
Anonymous voting

📌 Что такое асинхронное программирование? 💬 Спрашивают в 11% собеседований Асинхронное программирование — это метод программирования, при котором выполнение задач не блокирует основной поток приложения. Это позволяет улучшить производительность и отзывчивость приложений, особенно при выполнении длительных операций, таких как ввод-вывод (I/O), сетевые запросы или взаимодействие с базами данных. 🤔 Основные концепции 1️⃣ Асинхронные методы: Методы, которые выполняются асинхронно, часто обозначаются ключевыми словами async и await в C#. 2️⃣ Task: Основная единица работы в асинхронном программировании в C#. Объект Task представляет собой операцию, которая может выполняться асинхронно. 3️⃣ Await: Оператор, который указывает на то, что выполнение метода должно ожидать завершения асинхронной операции. 4️⃣ I/O Bound: Операции, которые зависят от ввода-вывода и обычно требуют времени ожидания (например, сетевые запросы, чтение/запись файлов). 5️⃣ CPU Bound: Операции, которые требуют значительных вычислительных ресурсов процессора. 🤔 Преимущества асинхронного программирования 1️⃣ Повышенная производительность: Основной поток не блокируется при выполнении длительных операций. 2️⃣ Отзывчивость интерфейса: Приложения остаются отзывчивыми, даже при выполнении длительных операций. 3️⃣ Лучшее использование ресурсов: Асинхронные операции позволяют более эффективно использовать ресурсы системы. 🤔 Пример асинхронного программирования в C# 🤔 Асинхронный метод
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        string url = "https://api.example.com/data";
        string result = await FetchDataAsync(url);
        Console.WriteLine(result);
    }

    static async Task<string> FetchDataAsync(string url)
    {
        using (HttpClient client = new HttpClient())
        {
            HttpResponseMessage response = await client.GetAsync(url);
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
    }
}
🤔 Объяснение кода 1️⃣ async: Ключевое слово, которое указывает, что метод является асинхронным. Методы Main и FetchDataAsync объявлены с async. 2️⃣ await: Оператор, который приостанавливает выполнение метода до завершения асинхронной операции. В методе FetchDataAsync await используется для ожидания завершения операций GetAsync и ReadAsStringAsync. 3️⃣ Task: Возвращаемый тип метода FetchDataAsync, представляющий асинхронную операцию, которая возвращает строку. 🤔 Асинхронное программирование с Task и Task<T> 🤔 Пример с Task
static async Task Main(string[] args)
{
    await Task.Run(() => DoWork());
}

static void DoWork()
{
    // Выполнение длительной операции
    Console.WriteLine("Работа выполнена.");
}
🤔 Асинхронное программирование с I/O Bound операциями 🤔 Пример с чтением файла
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        string filePath = "example.txt";
        string content = await ReadFileAsync(filePath);
        Console.WriteLine(content);
    }

    static async Task<string> ReadFileAsync(string filePath)
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            return await reader.ReadToEndAsync();
        }
    }
}
🤔 Краткий ответ Асинхронное программирование позволяет выполнять длительные операции без блокировки основного потока, улучшая производительность и отзывчивость приложений. В C# это реализуется с использованием ключевых слов async и await, а также класса Task. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

Регистрируйтесь на главную конференцию Yandex Cloud! Большая конференция Yandex Cloud для тех, кто создаёт цифровые продукты
Регистрируйтесь на главную конференцию Yandex Cloud! Большая конференция Yandex Cloud для тех, кто создаёт цифровые продукты и решения. Вас ждут 5 тематических треков, 31 доклад, 50 экспертов, нетворкинг и общение. Участие бесплатное! Зарегистрироваться #реклама 16+ scale.yandex.cloud О рекламодателе

🤔 Как сборщик мусора в C# освобождает память?
Anonymous voting

📌 Что такое параллелизм? 💬 Спрашивают в 11% собеседований Параллелизм в программировании — это метод выполнения нескольких операций одновременно, что позволяет ускорить выполнение задач и эффективно использовать ресурсы компьютера, такие как многоядерные процессоры. Параллелизм отличается от многозадачности тем, что он предполагает одновременное выполнение задач, а не просто чередование выполнения. 🤔 Основные концепции параллелизма 1️⃣ Параллельное выполнение (Parallel Execution): Одновременное выполнение нескольких задач на разных процессорных ядрах. 2️⃣ Потоки (Threads): Наименьшие единицы выполнения, которые могут быть параллельно выполнены. 3️⃣ Задачи (Tasks): Абстракция над потоками, позволяющая проще управлять параллельными операциями. 4️⃣ Асинхронное программирование (Asynchronous Programming): Выполнение операций без блокировки основного потока, часто используется в сочетании с параллелизмом. 🤔 Пример использования параллелизма в C# 🤔 С использованием `Parallel.For`
using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        Parallel.For(0, 10, i =>
        {
            Console.WriteLine($"Task {i} is running on thread {Task.CurrentId}");
        });
    }
}
🤔 С использованием `Task.Run`
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var task1 = Task.Run(() => DoWork("Task 1"));
        var task2 = Task.Run(() => DoWork("Task 2"));
        
        await Task.WhenAll(task1, task2);
    }

    static void DoWork(string taskName)
    {
        Console.WriteLine($"{taskName} is running on thread {Task.CurrentId}");
    }
}
🤔 Основные библиотеки и пространства имен в C# 1️⃣ System.Threading.Tasks: Основное пространство имен для работы с задачами (Task) и параллельным выполнением. 2️⃣ System.Threading: Предоставляет классы и интерфейсы для работы с потоками и задачами низкого уровня. 3️⃣ Parallel LINQ (PLINQ): Расширение LINQ для параллельного выполнения запросов. 🤔 Преимущества параллелизма 1️⃣ Ускорение выполнения задач: Позволяет значительно уменьшить время выполнения вычислительно интенсивных задач. 2️⃣ Эффективное использование ресурсов: Максимально использует мощности многоядерных процессоров. 3️⃣ Масштабируемость: Обеспечивает более плавную работу приложений при увеличении нагрузки. 🤔 Краткий ответ Параллелизм — это метод одновременного выполнения нескольких задач для ускорения процессов и эффективного использования ресурсов компьютера. В C# это реализуется через Parallel и Task классы, позволяя выполнять задачи на разных процессорных ядрах одновременно. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

🤔 Что произойдет, если вызвать метод Equals() для двух различных объектов, которые содержат одинаковые данные?
Anonymous voting

📌 Что такое исключения? 💬 Спрашивают в 11% собеседований Исключения в программировании — это механизмы обработки ошибок и необычных ситуаций, которые возникают во время выполнения программы. В C# и других языках программирования исключения позволяют отделить код обработки ошибок от основного кода программы, что упрощает его чтение и поддержку. 🤔 Основные понятия 1️⃣ Исключение (Exception): Событие, которое прерывает нормальный поток выполнения программы. 2️⃣ Блок try: Содержит код, который может вызвать исключение. 3️⃣ Блок catch: Содержит код, который выполняется, если возникает исключение. В catch блок можно передать параметр — экземпляр исключения, которое произошло. 4️⃣ Блок finally: Содержит код, который выполняется в любом случае, независимо от того, произошло исключение или нет. Обычно используется для освобождения ресурсов. 5️⃣ Бросание исключения (throw): Механизм для явного вызова исключения. 🤔 Пример использования 🤔 Основные блоки
try
{
    // Код, который может вызвать исключение
    int divisor = 0;
    int result = 10 / divisor;
}
catch (DivideByZeroException ex)
{
    // Обработка исключения
    Console.WriteLine("Деление на ноль невозможно.");
}
finally
{
    // Код, который выполнится в любом случае
    Console.WriteLine("Блок finally выполнен.");
}
🤔 Создание и бросание собственного исключения
public class InvalidAgeException : Exception
{
    public InvalidAgeException(string message) : base(message) { }
}

public void SetAge(int age)
{
    if (age < 0)
    {
        throw new InvalidAgeException("Возраст не может быть отрицательным.");
    }
    // Логика установки возраста
}
🤔 Краткий ответ Исключения — это механизм обработки ошибок в C#, позволяющий отделить код обработки ошибок от основного кода программы. Основные элементы включают блоки try, catch, finally, а также оператор throw для явного вызова исключений. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

Прокачаем ваш frontend скилл с junior до middle Научим писать код, который не стыдно показать Первые 7 дней бесплатно. Попроб
Прокачаем ваш frontend скилл с junior до middle Научим писать код, который не стыдно показать Первые 7 дней бесплатно. Попробуй! Узнать больше #реклама 16+ ykul.ru О рекламодателе

🤔 Какой метод из перечисленных используется для преобразования строки в число?
Anonymous voting

📌 Какие бывают коллекции? 💬 Спрашивают в 11% собеседований В C# существует множество коллекций, каждая из которых предназначена для различных сценариев использования. Они предоставляются через стандартную библиотеку .NET и могут быть разделены на несколько категорий: 🤔 Основные категории коллекций 1️⃣ Коллекции общего назначения 2️⃣ Специализированные коллекции 3️⃣ Параллельные коллекции 🤔 Коллекции общего назначения 1️⃣ List<T>: Динамический массив, который автоматически изменяет свой размер по мере добавления элементов.
   List<int> numbers = new List<int> { 1, 2, 3, 4 };
   numbers.Add(5);
   
2️⃣ Dictionary<TKey, TValue>: Коллекция пар ключ-значение. Обеспечивает быстрый доступ к значению по ключу.
   Dictionary<string, int> ages = new Dictionary<string, int>
   {
       { "Alice", 30 },
       { "Bob", 25 }
   };
   int aliceAge = ages["Alice"];
   
3️⃣ HashSet<T>: Коллекция уникальных элементов. Используется для предотвращения дублирования.
   HashSet<string> fruits = new HashSet<string> { "Apple", "Banana" };
   fruits.Add("Apple"); // Не добавит дубликат
   
4️⃣ Queue<T>: Очередь, работающая по принципу FIFO (First In, First Out).
   Queue<string> queue = new Queue<string>();
   queue.Enqueue("first");
   queue.Enqueue("second");
   string item = queue.Dequeue(); // "first"
   
5️⃣ Stack<T>: Стек, работающий по принципу LIFO (Last In, First Out).
   Stack<string> stack = new Stack<string>();
   stack.Push("first");
   stack.Push("second");
   string item = stack.Pop(); // "second"
   
🤔 Специализированные коллекции 1️⃣ LinkedList<T>: Двусвязный список, позволяющий быстро вставлять и удалять элементы.
   LinkedList<int> linkedList = new LinkedList<int>();
   linkedList.AddLast(1);
   linkedList.AddLast(2);
   
2️⃣ SortedList<TKey, TValue>: Коллекция пар ключ-значение, отсортированная по ключам.
   SortedList<string, int> sortedList = new SortedList<string, int>
   {
       { "Alice", 30 },
       { "Bob", 25 }
   };
   
3️⃣ SortedDictionary<TKey, TValue>: Похож на SortedList, но использует бинарное дерево для хранения элементов.
   SortedDictionary<string, int> sortedDict = new SortedDictionary<string, int>
   {
       { "Alice", 30 },
       { "Bob", 25 }
   };
   
4️⃣ SortedSet<T>: Отсортированное множество уникальных элементов.
   SortedSet<int> sortedSet = new SortedSet<int> { 3, 1, 2 };
   
🤔 Параллельные коллекции 1️⃣ ConcurrentDictionary<TKey, TValue>: Параллельная версия Dictionary, предназначенная для безопасного использования в многопоточных приложениях.
   ConcurrentDictionary<string, int> concurrentDict = new ConcurrentDictionary<string, int>();
   concurrentDict.TryAdd("Alice", 30);
   
2️⃣ ConcurrentQueue<T>: Параллельная версия Queue.
   ConcurrentQueue<string> concurrentQueue = new ConcurrentQueue<string>();
   concurrentQueue.Enqueue("first");
   
3️⃣ ConcurrentStack<T>: Параллельная версия Stack.
   ConcurrentStack<string> concurrentStack = new ConcurrentStack<string>();
   concurrentStack.Push("first");
   
4️⃣ BlockingCollection<T>: Коллекция, поддерживающая операции добавления и извлечения с блокировкой и ограничением по емкости.
   BlockingCollection<int> blockingCollection = new BlockingCollection<int>(5);
   blockingCollection.Add(1);
   
🤔 Краткий ответ В C# есть множество коллекций для различных целей, включая List, Dictionary, HashSet, Queue, Stack, специализированные коллекции, такие как LinkedList, SortedList, и параллельные коллекции, такие как ConcurrentDictionary и BlockingCollection. Каждая коллекция имеет свои особенности и предназначена для определенных сценариев использования. 🔥 ТОП ВОПРОСОВ С СОБЕСОВ 🔒 База собесов | 🔒 База тестовых

Обучение на Frontend-разработчика. С нуля за 9 месяцев. На курсе вы получите все навыки, необходимые для старта в профессии Frontend-разработчика. Дистанционное обучение. Персональный наставник middle/senior уровня. 14 проектов, лайвкодинг, хакатоны, репетиции техсобеседования. Освоите JavaScript, React, TypeScript Официальный диплом и сертификат школы. Гарантия трудоустройства. Если вы не устроитесь, вернём деньги. Это закреплено в договоре п. 6.14. До 22 сентября скидка 30% на все курсы Result University Узнать больше #реклама 16+ result.school О рекламодателе

C# | Вопросы собесов - Статистика и аналитика Telegram-канала @easy_c_sharp