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

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

Kanalga Telegram’da o‘tish
5 063
Obunachilar
+224 soatlar
Ma'lumot yo'q7 kunlar
-1030 kunlar
Postlar arxiv
🤔 Что такое .NET стандарт? .NET Standard — это спецификация API, которая определяет набор базовых библиотек, доступных во всех реализациях .NET (например, .NET Framework, .NET Core, Xamarin, Unity и других). Она была создана для обеспечения совместимости между разными платформами .NET. 🚩Зачем нужен .NET Standard? До появления .NET Standard существовало несколько отдельных реализаций .NET: .NET Framework (для Windows-приложений) .NET Core (кроссплатформенная версия .NET) Mono/Xamarin (для мобильных и игровых приложений) Каждая из них имела свои особенности и набор доступных API. Из-за этого разработчики, создавая библиотеку, сталкивались с проблемой совместимости: приходилось писать несколько версий кода под разные платформы или использовать Portable Class Library (PCL), которая имела ограниченный функционал. .NET Standard решил эту проблему, введя единый набор API, который обязаны поддерживать все реализации .NET. 🚩Как это работает? .NET Standard представляет собой абстрактную спецификацию API, которая реализуется разными версиями .NET. Например, .NET Standard 2.0 поддерживается в .NET Framework 4.6.1, .NET Core 2.0 и выше. Если библиотека написана под .NET Standard 2.0, её можно использовать во всех этих средах. 🚩Версии .NET Standard Существуют разные версии .NET Standard, каждая из которых включает больше API, чем предыдущая. Чем выше версия, тем больше возможностей, но и тем меньше совместимость с более старыми реализациями .NET. 🚩Пример использования Создаём Class Library с таргетом .NET Standard 2.0:
   namespace MyLibrary
   {
       public class MathHelper
       {
           public static int Add(int a, int b)
           {
               return a + b;
           }
       }
   }
Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое DI (инъекция зависимости)? Это способ передачи зависимостей в объект вместо их создания внутри объекта. 1. Позволяет строить слабо связанный код и облегчает тестирование. 2. Реализуется через конструкторы, свойства или методы. 3. Используется для улучшения гибкости и модульности приложений. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Что такое Generic-и? Термин "Generic" (общий тип) относится к функциональности, позволяющей определять классы, интерфейсы или методы с использованием параметра типа, который определяется в момент создания экземпляра класса или вызова метода. Обобщённые типы широко используются для повышения повторного использования кода, типобезопасности и производительности. Как и во многих других языках программирования, generics представляют собой мощный инструмент, который устраняет необходимость в чрезмерном приведении типов и может уменьшить количество дублирующего кода. 🚩Основы Пример использования Generic-ов в классе
public class GenericList<T>
{
    private T[] elements;
    private int size;

    public GenericList(int size)
    {
        elements = new T[size];
        this.size = size;
    }

    public void Add(T element)
    {
        // Логика добавления элемента
    }

    public T this[int i]
    {
        get { return elements[i]; }
        set { elements[i] = value; }
    }
}
Пример использования Generic-ов в методе
public T GenericMax<T>(T x, T y) where T : IComparable
{
    return x.CompareTo(y) > 0 ? x : y;
}
🚩ПлюсыПовышение переиспользуемости кода Обобщённые классы и методы могут работать с любым типом данных, что позволяет разработчикам использовать один и тот же код для данных различных типов. ➕Типобезопасность Generics обеспечивают проверку типов на этапе компиляции. Это улучшает безопасность и стабильность кода, уменьшая риск возникновения ошибок во время выполнения программы из-за некорректного приведения типов. ➕Улучшение производительности Использование generics может помочь улучшить производительность, т.к. уменьшает необходимость в приведении типов, которое может быть дорогостоящим в плане ресурсов процессора. Ставь 👍 и забирай 📚 Базу знаний

🤔 Примеры паттерна абстрактной фабрики? Абстрактная фабрика — это паттерн, который позволяет создавать семейства взаимосвязанных объектов, не привязываясь к конкретным классам. Пример: В графической системе можно иметь: - Button и Checkbox для Windows, - Button и Checkbox для macOS. Абстрактная фабрика позволяет создавать соответствующие элементы без знания, для какой платформы они реализованы. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Если в двух переменных хранится одинаковое значение, то будут ли они равны? Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения. 🟠Примитивные типы (Value Types) Для примитивных типов (например, int, float, char, bool) значение хранятся непосредственно в переменных, и их сравнение выполняется по значению.
int a = 5;
int b = 5;

bool areEqual = (a == b); // True
🟠Ссылочные типы (Reference Types) Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
class Person
{
    public string Name { get; set; }
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = (person1 == person2); // False, потому что сравниваются ссылки
🟠Строки (Strings) Строки являются ссылочными типами, но переопределяют операторы сравнения == и Equals для сравнения по значению.
string str1 = "Hello";
string str2 = "Hello";

bool areEqual = (str1 == str2); // True, строки сравниваются по значению
🟠Кастомные классы Для кастомных классов можно переопределить методы Equals и GetHashCode, чтобы сравнивать объекты по значению.
class Person
{
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
            return false;

        Person other = (Person)obj;
        return Name == other.Name;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}

Person person1 = new Person { Name = "Alice" };
Person person2 = new Person { Name = "Alice" };

bool areEqual = person1.Equals(person2); // True
Ставь 👍 и забирай 📚 Базу знаний

Оценивать влияние медийной рекламы стало проще Теперь исследование Target Lift может учитывать не только веб-конверсии, но и
Оценивать влияние медийной рекламы стало проще Теперь исследование Target Lift может учитывать не только веб-конверсии, но и in-app события (заказы, заявки и другие действия в приложении) после контакта с медийной рекламой. ⚡Это особенно полезно для бизнесов, где приложение — один из ключевых каналов взаимодействия с аудиторией. По результатам тестов, у таких бизнесов количество исследований со статистически значимыми приростами увеличивается на 60% по сравнению с результатами, которые они получали при анализе только веб-трафика. Для настройки можно использовать AppMetrica, Adjust или AppsFlyer. При использовании Adjust или AppsFlyer важно настроить передачу данных по всем рекламным источникам, чтобы корректно учитывать post-view конверсии и получать более полную аналитику. Подробнее в статье Перейти на сайт #реклама 16+ yandex.ru О рекламодателе

Онлайн-магистратура МФТИ: Науки о данных (Data Science) 🎓Диплом как реальный стартап, проект или исследование. Менторство от экспертов индустрии и выход на инвестиции. Узнать больше #реклама 16+ mipt.online О рекламодателе

Главный навык на ближайшие годы — ВАЙБ-КОДИНГ ИИ уже пишет код, чинит баги, генерирует тесты, документацию и помогает запуска
Главный навык на ближайшие годы — ВАЙБ-КОДИНГ ИИ уже пишет код, чинит баги, генерирует тесты, документацию и помогает запускать продукты быстрее, чем это делали классические команды разработки. И это уже не "будущее когда-нибудь", а реальность, которая меняет рынок уже сегодня И те, кто научится вайбкодить сейчас, будут увереннее конкурировать на рынке и зарабатывать больше тех, кто по-прежнему делает всё вручную. Стартовать с нуля поможет канал Вайб-кодинг. Там ребята круглосуточно мониторят более 320 российских и зарубежных источников и публикуют только главное: релизы, инструменты, гайды, курсы и практические кейсы. Подписывайтесь, нас уже 30 тысяч: @vibecoding_tg

Не грузится? Понимаем. Бесплатный мессенджер для вашей компании - Битрикс24. Личные и групповые чаты, видеозвонки, каналы и н
Не грузится? Понимаем. Бесплатный мессенджер для вашей компании - Битрикс24. Личные и групповые чаты, видеозвонки, каналы и нейросеть. Всё привычно и удобно. Начните работать на бесплатном тарифе уже сейчас. Узнать больше #реклама 16+ bitrix24.ru О рекламодателе

🤔 Какой слой rest и swap с точки зрения трехслойной архитектуры? В трехслойной архитектуре (трехуровневая архитектура), также известной как многоуровневая архитектура, приложения разделяются на три логических слоя: 🟠Презентационный слой (Presentation Layer) Отвечает за взаимодействие с пользователем. Веб-интерфейсы, мобильные приложения, десктопные приложения. Примеры: HTML/CSS/JavaScript для веб-приложений, UI-компоненты в мобильных и десктопных приложениях. 🟠Логический слой (Business Logic Layer) Содержит бизнес-логику и правила приложения. Обрабатывает данные, выполняет вычисления, применяет бизнес-правила. Примеры: классы и методы, реализующие бизнес-логику, сервисы, обработчики данных. 🟠Слой данных (Data Access Layer): Отвечает за взаимодействие с источниками данных. Операции с базами данных, файловыми системами, внешними сервисами. Примеры: репозитории, Data Access Objects (DAO), API-клиенты для доступа к внешним системам. 🚩REST REST — это архитектурный стиль для разработки веб-сервисов. RESTful сервисы используют стандартные HTTP методы (GET, POST, PUT, DELETE и т.д.) для работы с ресурсами. С точки зрения трехслойной архитектуры: Презентационный слой: Вызовы REST API могут происходить с клиентской стороны (например, AJAX запросы из веб-интерфейса) или через клиентские приложения. Пример: фронтенд веб-приложения, который взаимодействует с REST API. Логический слой: REST API реализует бизнес-логику и выступает посредником между презентационным слоем и слоем данных. Пример: контроллеры и сервисы, обрабатывающие REST запросы и выполняющие соответствующую бизнес-логику. Слой данных: REST API может взаимодействовать с базой данных или другими источниками данных для получения и сохранения информации. Пример: методы в API, которые выполняют запросы к базе данных через репозитории или DAO. 🚩SWAP SWAP — это гипотетический или менее распространенный термин, часто интерпретируемый как упрощенный API для веб-приложений. Презентационный слой Клиентские приложения или пользовательские интерфейсы могут вызывать методы SWAP для получения или отправки данных.Пример: веб-страницы или мобильные приложения, обращающиеся к SWAP для выполнения операций. Логический слой: SWAP обрабатывает бизнес-логику аналогично REST API, предоставляя упрощенные конечные точки для взаимодействия с данными. Пример: сервисы, которые реализуют простые операции (CRUD) без сложной бизнес-логики. Слой данных: SWAP взаимодействует с базой данных или другими источниками данных для выполнения операций чтения/записи. Пример: методы SWAP, которые обращаются к базе данных через абстрактные уровни доступа к данным. Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое делегат? Делегат в C# — это тип, который представляет ссылки на методы с определённой сигнатурой. Делегаты используются для передачи методов в качестве параметров и для обратных вызовов (callbacks). Они являются основой для событий и лямбда-выражений в C#. Делегаты позволяют вызывать методы динамически, что делает код более гибким. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Какая есть классификация у кучи? В информатике и программировании куча (heap) может классифицироваться по нескольким критериям. Рассмотрим основные виды: 🟠По назначению: Куча памяти (Memory Heap) Используется для динамического выделения памяти в приложениях. В C# это управляется сборщиком мусора (GC - Garbage Collector). Примеры: объекты, созданные с помощью new, выделяются в управляемой куче. 🟠Структура данных «Куча» (Heap Data Structure) Это специальная бинарная структура данных, используемая в алгоритмах, например, в сортировке (Heap Sort) или в приоритетных очередях. Бывает максимальная куча (max-heap) и минимальная куча (min-heap). 🚩По типу управления памятью (для кучи памяти в языках программирования): 🟠Управляемая куча (Managed Heap) В C# и .NET память выделяется и освобождается автоматически с помощью GC. Разделяется на поколения (Generation 0, 1, 2), что оптимизирует работу сборщика мусора. 🟠Неуправляемая куча (Unmanaged Heap) Применяется в C/C++ и низкоуровневом коде, где управление памятью выполняется вручную (malloc/free, new/delete). В C# тоже можно работать с ней через Marshal или Unsafe код. 🟠По структуре данных (Heap Data Structure): 🟠Максимальная куча (Max Heap) Корневой узел содержит наибольшее значение, а дочерние узлы – меньшее. Используется в алгоритмах приоритетных очередей. 🟠Минимальная куча (Min Heap) Корневой узел содержит наименьшее значение, а дочерние узлы – большее. Применяется в алгоритме Дейкстры и других задачах.
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        PriorityQueue<int, int> minHeap = new PriorityQueue<int, int>();

        minHeap.Enqueue(5, 5);
        minHeap.Enqueue(3, 3);
        minHeap.Enqueue(8, 8);
        minHeap.Enqueue(1, 1);

        while (minHeap.Count > 0)
        {
            Console.WriteLine(minHeap.Dequeue()); // Выведет: 1, 3, 5, 8
        }
    }
}
Ставь 👍 и забирай 📚 Базу знаний

🤔 Для чего нужно разделение Large Object Heap и Small Object Heap? Разделение позволяет оптимизировать работу сборщика мусора, так как большие объекты редко перемещаются, а их обработка происходит отдельно, минимизируя накладные расходы. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Возможно ли как-нибудь ограничить типы, которые пользователь будет передавать через шаблон? Можно ограничить типы, которые передаются в шаблоны (generics), с помощью ключевого слова where. Это позволяет указать, какие типы подходят для использования, обеспечивая безопасность и предсказуемость кода. Вот основные виды ограничений: 🟠Класс или структура where T : class — только классы. where T : struct — только структуры. 🟠Интерфейс Указание интерфейса, который должен реализовать тип:
   public class MyClass<T> where T : IDisposable { }
   
🟠Базовый класс Указание, что тип должен быть наследником определённого класса:
   public class MyClass<T> where T : Exception { }
   
🟠Конструктор Ограничение на наличие конструктора без параметров:
   public class MyClass<T> where T : new() { }
   
🟠Комбинированные ограничения Можно объединять несколько условий:
   public class MyClass<T> where T : class, IDisposable, new() { }
Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое Inversion of control и dependency injection? Inversion of control (IoC) — это принцип, при котором управление созданием объектов передается внешним компонентам. Dependency injection (DI) — это один из способов реализации IoC, когда зависимости передаются объекту через конструктор, методы или свойства. Это позволяет улучшить тестируемость и модульность кода. DI делает систему более гибкой, позволяя изменять реализации зависимостей без изменения кода. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Какие есть модификаторы доступа? Есть модификаторы доступа, которые определяют, кто может использовать классы, методы и переменные. Они помогают скрыть внутренние детали кода и контролировать доступ к данным. 🚩Подробное объяснение с примерами 🟠`public` (Открытый доступ) Открытый доступ означает, что элемент можно использовать везде.
public class Car
{
    public string Model = "Tesla";
}

class Program
{
    static void Main()
    {
        Car car = new Car();
        Console.WriteLine(car.Model); // Доступ открыт
    }
}
🟠`private` (Только внутри класса) Самый закрытый модификатор. Поля и методы невидимы за пределами класса.
class Car
{
    private string model = "Tesla";

    private void PrintModel()
    {
        Console.WriteLine(model);
    }
}

class Program
{
    static void Main()
    {
        Car car = new Car();
        // car.model = "BMW";   Ошибка! Поле `model` — private
        // car.PrintModel();  Ошибка! Метод `PrintModel` — private
    }
}
🟠`protected` (Доступен в наследниках) Доступен только внутри класса и его наследников.
class Car
{
    protected string Model = "Tesla";
}

class ElectricCar : Car
{
    public void ShowModel()
    {
        Console.WriteLine(Model); //  Можно, потому что наследуемый класс
    }
}

class Program
{
    static void Main()
    {
        ElectricCar eCar = new ElectricCar();
        // eCar.Model  Ошибка! Поле `Model` доступно только в наследниках
    }
}
🟠`internal` (Только внутри проекта) Элементы с internal можно использовать только внутри одной сборки (проекта).
internal class Engine
{
    public void Start() => Console.WriteLine("Двигатель запущен");
}

class Program
{
    static void Main()
    {
        Engine engine = new Engine();
        engine.Start(); //  Работает, потому что внутри того же проекта
    }
}
🟠`protected internal` (В сборке и у наследников) Этот модификатор разрешает доступ внутри сборки, а также в классах-наследниках за её пределами.
public class Car
{
    protected internal string Model = "Tesla";
}

class ElectricCar : Car
{
    public void ShowModel()
    {
        Console.WriteLine(Model); //  Можно, потому что наследник
    }
}
🟠`private protected` (Только в классе и наследниках из той же сборки) Этот модификатор ещё жёстче, чем protected internal: - Доступ внутри класса – да - В наследниках – только внутри той же сборки - В других проектах – нет доступа!
class Car
{
    private protected string Model = "Tesla";
}

class ElectricCar : Car
{
    public void ShowModel()
    {
        Console.WriteLine(Model); //  Можно, потому что наследник в той же сборке
    }
}

class Program
{
    static void Main()
    {
        ElectricCar eCar = new ElectricCar();
        // eCar.Model  Ошибка! `Model` доступен только в наследниках из этой сборки
    }
}
Ставь 👍 и забирай 📚 Базу знаний

🤔 Что такое стек? Стек — это структура данных LIFO, где последний добавленный элемент извлекается первым, используется для вызовов функций и локальных переменных. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Как сейчас делается Singleton? В современном C# паттерн Singleton можно реализовать несколькими способами, каждый из которых имеет свои преимущества и предназначен для различных сценариев использования. Рассмотрим несколько распространенных подходов к реализации Singleton. 🟠Ленивый Singleton (Lazy Initialization) Ленивый Singleton инициализируется при первом обращении. Это обеспечивает отложенную инициализацию объекта и гарантирует потокобезопасность.
public class Singleton
{
    private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance => lazyInstance.Value;

    private Singleton()
    {
        // Приватный конструктор
    }
}
🟠Потокобезопасный Singleton (Thread-safe) Этот подход использует lock для обеспечения потокобезопасности при создании экземпляра.
public class Singleton
{
    private static Singleton instance;
    private static readonly object lockObj = new object();

    private Singleton()
    {
        // Приватный конструктор
    }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                lock (lockObj)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}
Eager Initialization (Инициализация при загрузке) Экземпляр Singleton создается при загрузке класса. Это гарантирует потокобезопасность за счет особенностей инициализации статических переменных в .NET.
public class Singleton
{
    private static readonly Singleton instance = new Singleton();

    public static Singleton Instance => instance;

    private Singleton()
    {
        // Приватный конструктор
    }
}
🟠Static Constructor (Статический конструктор) Использование статического конструктора для инициализации Singleton.
public class Singleton
{
    private static readonly Singleton instance;

    static Singleton()
    {
        instance = new Singleton();
    }

    public static Singleton Instance => instance;

    private Singleton()
    {
        // Приватный конструктор
    }
}
Singleton с внедрением зависимостей (Dependency Injection) В современных приложениях, особенно с использованием ASP.NET Core, Singleton часто регистрируется в контейнере внедрения зависимостей.
public class SingletonService
{
    public void DoWork()
    {
        // Выполнение работы
    }
}

// Регистрация в контейнере служб
public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<SingletonService>();
}

// Использование в контроллере
public class MyController : ControllerBase
{
    private readonly SingletonService _singletonService;

    public MyController(SingletonService singletonService)
    {
        _singletonService = singletonService;
    }

    public IActionResult Index()
    {
        _singletonService.DoWork();
        return Ok();
    }
}
Ставь 👍 и забирай 📚 Базу знаний

🤔 Какие ресурсы очищают Dispose и Finalize? - Dispose используется для ручного освобождения ресурсов, таких как: - Файлы - Соединения с базами данных - Сетевые сокеты - Таймеры и обработчики событий - Finalize вызывается автоматически сборщиком мусора, чтобы освободить неуправляемые ресурсы (например, дескрипторы ОС, ресурсы вне .NET). Dispose — быстрее и надёжнее, потому что вызывается явно, в отличие от непредсказуемого Finalize. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 В каком случае использовать интерфейс, в каком абстрактный класс? Выбор между интерфейсом и абстрактным классом в C# зависит от нескольких факторов, таких как потребности в наследовании, степень общности, возможность множественного наследования и необходимость реализации по умолчанию. 🚩Когда использовать интерфейсы 🟠Множественное наследование Класс может реализовывать несколько интерфейсов, но наследоваться только от одного класса. Используйте интерфейсы, когда требуется множественное наследование.
public interface IDriveable
{
void Drive();
}

   public interface IFlyable
   {
   void Fly();
   }

public class FlyingCar : IDriveable, IFlyable
{
public void Drive() { /* Реализация вождения */ }
public void Fly() { /* Реализация полета */ }
}
🟠Общее поведение без реализации Используйте интерфейсы, чтобы определить общий набор методов и свойств без предоставления какой-либо реализации. Это позволяет разным классам реализовать интерфейс по-своему.
public interface IShape
{
double GetArea();
}

public class Circle : IShape
{
public double Radius { get; set; }
public double GetArea() => Math.PI * Radius * Radius;
}

public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double GetArea() => Width * Height;
}
🟠Гибкость и полиморфизм Интерфейсы позволяют легко менять реализацию и обеспечивают гибкость в коде. Можно использовать интерфейсы для создания полиморфных коллекций или методов, которые работают с разными реализациями интерфейсов.
public void DrawShapes(IEnumerable<IShape> shapes)
{
foreach (var shape in shapes)
{
Console.WriteLine($"Area: {shape.GetArea()}");
}
}
🚩Когда использовать 🟠Частичная реализация Используйте абстрактные классы, если вы хотите предоставить некоторую общую реализацию, которую могут использовать подклассы. Абстрактные классы могут содержать как абстрактные, так и не абстрактные методы.
public abstract class Animal
{
public abstract void MakeSound();
public void Sleep() => Console.WriteLine("Sleeping");
}

public class Dog : Animal
{
public override void MakeSound() => Console.WriteLine("Bark");
}
🟠Шаблонный метод Абстрактные классы хорошо подходят для реализации паттерна "Шаблонный метод", где общий алгоритм реализован в абстрактном классе, а конкретные шаги определены в подклассах.
public abstract class Game
{
public void Play()
{
Initialize();
StartPlay();
EndPlay();
}

protected abstract void Initialize();
protected abstract void StartPlay();
protected abstract void EndPlay();
}

public class Football : Game
{
protected override void Initialize() => Console.WriteLine("Football Game Initialized");
protected override void StartPlay() => Console.WriteLine("Football Game Started");
protected override void EndPlay() => Console.WriteLine("Football Game Ended");
}
Ставь 👍 и забирай 📚 Базу знаний