C# | Вопросы собесов
5.1K subscribers
35 photos
1 file
982 links
Download Telegram
🤔 Что такое EF?

EF (Entity Framework) — это ORM (Object-Relational Mapping) для .NET, облегчающая работу с базами данных. С помощью EF разработчики могут манипулировать данными как объектами C# без необходимости писать SQL-код. Он автоматически преобразует объекты в SQL-запросы и обратно.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Как работают join`ы?

join в LINQ используется для объединения двух последовательностей на основе соответствия ключей. Вот краткие примеры, показывающие, как работают join в LINQ.

🚩Основные типы

🟠Inner Join
Соединяет элементы двух коллекций, если их ключи совпадают.
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };


🟠Group Join
Создает группы элементов из второй коллекции, соответствующие каждому элементу из первой коллекции.
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
select new { user.Name, Orders = userOrders };


🟠Left Join (нет прямой поддержки, можно имитировать с помощью DefaultIfEmpty)
Возвращает все элементы из первой коллекции и соответствующие элементы из второй коллекции, если они существуют.
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
from order in userOrders.DefaultIfEmpty()
select new { user.Name, OrderId = order?.OrderId };


🚩Примеры

Данных
var users = new List<User>
{
new User { Id = 1, Name = "Alice" },
new User { Id = 2, Name = "Bob" }
};

var orders = new List<Order>
{
new Order { OrderId = 101, UserId = 1 },
new Order { OrderId = 102, UserId = 1 },
new Order { OrderId = 103, UserId = 2 }
};


Inner Join
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };

foreach (var item in query)
{
Console.WriteLine($"{item.Name} - {item.OrderId}");
}


Group Join
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
select new { user.Name, Orders = userOrders };

foreach (var item in query)
{
Console.WriteLine($"{item.Name} has {item.Orders.Count()} orders");
}


Left Join
var query = from user in users
join order in orders on user.Id equals order.UserId into userOrders
from order in userOrders.DefaultIfEmpty()
select new { user.Name, OrderId = order?.OrderId };

foreach (var item in query)
{
Console.WriteLine($"{item.Name} - {item.OrderId}");
}


Ставь
👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥52👍2
🤔 В чем разница между асинхронностью и многопоточностью?

Асинхронность позволяет выполнять задачи без блокировки основного потока, в то время как многопоточность предполагает разделение кода на несколько потоков. Асинхронные операции выполняются в том же потоке, но не блокируют его, а многопоточность использует параллельные потоки для выполнения задач одновременно.\

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥21
🤔 Как оптимизировать ситуацию, когда к таблице много join`ов?

🟠Индексы
Создайте индексы на столбцах, используемых в условиях соединения (join).
CREATE INDEX idx_user_id ON Users(Id);
CREATE INDEX idx_order_user_id ON Orders(UserId);


🟠Избегайте ненужных полей
Выбирайте только необходимые столбцы, чтобы уменьшить объем данных.
var query = from user in users
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };


🟠Используйте отложенную загрузку (Lazy Loading)
Отложенная загрузка загружает данные только тогда, когда они действительно нужны.
var user = context.Users.Find(userId);
context.Entry(user).Collection(u => u.Orders).Load();


🟠Разделение на подзапросы
Разделите сложные запросы на подзапросы для улучшения читаемости и производительности.
var userIds = users.Select(u => u.Id).ToList();
var query = from order in orders
where userIds.Contains(order.UserId)
select order;


🟠Применяйте фильтрацию до join
Фильтруйте данные перед выполнением join, чтобы уменьшить размер соединяемых таблиц.
var filteredUsers = users.Where(u => u.IsActive);
var query = from user in filteredUsers
join order in orders on user.Id equals order.UserId
select new { user.Name, order.OrderId };


🟠Используйте оптимизированные ORM функции
Используйте функции ORM, которые могут генерировать более оптимизированные SQL-запросы.
var query = context.Users
.Where(u => u.IsActive)
.SelectMany(u => u.Orders, (user, order) => new { user.Name, order.OrderId });


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁2
🤔 Как используется ключевое слово await?

Ключевое слово await используется для приостановки выполнения метода до завершения асинхронной задачи. Оно позволяет освобождать текущий поток и возвращается к коду после завершения задачи. await применяется в асинхронных методах, объявленных с помощью async.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
🤔 Расскажи про метод ASP/Query?

Не является стандартным термином в ASP.NET или ASP.NET Core. Возможно, имеется в виду подход к созданию запросов или API-методов в ASP.NET Core для обработки HTTP-запросов. Рассмотрим, как создавать и обрабатывать запросы в ASP.NET Core.

🚩Создание и Обработка Запросов

🟠Создание контроллера
Контроллеры в ASP.NET Core отвечают за обработку HTTP-запросов и возврат ответов. Контроллеры обычно наследуются от класса ControllerBase или Controller.
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private readonly IUserService _userService;

public UsersController(IUserService userService)
{
_userService = userService;
}

[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
var user = _userService.GetUserById(id);
if (user == null)
{
return NotFound();
}
return Ok(user);
}

[HttpPost]
public IActionResult CreateUser([FromBody] User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
_userService.CreateUser(user);
return CreatedAtAction(nameof(GetUser), new { id = user.Id }, user);
}
}


🟠Создание сервиса
Сервисы содержат бизнес-логику приложения. Обычно они регистрируются в контейнере зависимостей.
public interface IUserService
{
User GetUserById(int id);
void CreateUser(User user);
}

public class UserService : IUserService
{
private readonly List<User> _users = new List<User>();

public User GetUserById(int id)
{
return _users.FirstOrDefault(u => u.Id == id);
}

public void CreateUser(User user)
{
user.Id = _users.Count + 1;
_users.Add(user);
}
}


🟠Модель данных
Модель данных представляет структуру данных, с которой работает приложение.
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}


🟠Регистрация сервисов в контейнере зависимостей
Регистрация сервисов в Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IUserService, UserService>();
}


🟠Настройка маршрутизации
Настройка маршрутизации для контроллеров в Startup.cs.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}


🚩Пример вызова API

GET-запрос для получения пользователя
GET /api/users/1


POST-запрос для создания пользователя
POST /api/users
Content-Type: application/json

{
"name": "Alice",
"age": 30
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 Что такое lock-еры?

Lock-еры — это объекты или механизмы, такие как lock в C#, которые предотвращают одновременный доступ к критическим участкам кода из нескольких потоков. Они обеспечивают безопасное выполнение кода в многопоточной среде, исключая гонки данных. Например, lock блокирует выполнение других потоков, пока текущий поток не завершит работу с ресурсом.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👀1
🤔 Что бывает, когда количества подключений не хватает?

🟠Отказы в подключении
Новые запросы к базе данных не могут быть обработаны, так как нет доступных подключений. Это приводит к тому, что запросы отклоняются или истекает время ожидания (timeout).

🟠Задержки и снижение производительности
Запросы могут быть помещены в очередь и ждать доступного подключения, что увеличивает время отклика и снижает производительность системы.

🟠Ошибки и исключения
Приложение может выбрасывать исключения, такие как TimeoutException, SqlException (например, Cannot open connection), указывающие на невозможность установления соединения.

🚩Примеры исключений

try
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
}
}
catch (SqlException ex)
{
Console.WriteLine("Ошибка подключения к базе данных: " + ex.Message);
}
catch (TimeoutException ex)
{
Console.WriteLine("Превышено время ожидания подключения: " + ex.Message);
}


🚩Причины исчерпания подключений

🟠Плохое управление подключениями
Неосвобождение ресурсов: Пул подключений может исчерпаться, если подключения не закрываются и не возвращаются в пул после использования. Длительное удержание подключений: Подключения удерживаются слишком долго, например, при выполнении долгих операций в одной сессии.
🟠Высокая нагрузка
Чрезмерное количество одновременно выполняемых запросов, превышающее максимальное количество доступных подключений в пуле.
🟠Неправильная настройка пула подключений
Недостаточное количество максимальных подключений в пуле или слишком большое время ожидания подключения.

🚩Способы решения проблемы

🟠Правильное управление подключениями
Всегда закрывайте соединения после использования, чтобы они возвращались в пул.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
connection.Close(); // Явно закрываем подключение
}


Используйте конструкцию using для автоматического закрытия соединений.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Выполнение операций с базой данных
} // Подключение автоматически закрывается здесь


🟠Настройка пула подключений
Увеличьте максимальное количество подключений в пуле.
var connectionString = "Data Source=server;Initial Catalog=database;User ID=user;Password=password;Max Pool Size=100;";


Настройте время ожидания подключения.
var connectionString = "Data Source=server;Initial Catalog=database;User ID=user;Password=password;Connection Timeout=30;";


🟠Оптимизация запросов и транзакций
Минимизируйте время удержания соединений. Используйте транзакции эффективно, чтобы не блокировать соединения на долгое время.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
// Выполнение операций с базой данных
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
🤔 Как работает сборка мусора на платформе .NET?

Сборка мусора (.NET Garbage Collector) автоматически управляет памятью, удаляя объекты, к которым нет ссылок. GC работает в нескольких поколениях, чтобы оптимизировать производительность, очищая короткоживущие объекты чаще. Он запускается, когда система нуждается в памяти или при достижении определённых условий.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
🤔 Как можно не используя middleware выполнить действие перед обработкой запроса и после?

В ASP.NET Core можно выполнять действия до и после обработки запроса, не используя middleware, с помощью фильтров действий (Action Filters). Фильтры позволяют выполнять код до и после вызова метода контроллера.

🚩Фильтры действий (Action Filters)

🟠Создание фильтра действия
Создадим фильтр, который выполняет код до и после метода действия контроллера.
using Microsoft.AspNetCore.Mvc.Filters;
using System;

public class MyActionFilter : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Код, выполняемый до действия контроллера
Console.WriteLine("До выполнения действия контроллера.");
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Код, выполняемый после действия контроллера
Console.WriteLine("После выполнения действия контроллера.");
}
}


🟠Применение фильтра к контроллеру или действию
Фильтр можно применить к конкретному методу контроллера или ко всему контроллеру.
using Microsoft.AspNetCore.Mvc;

public class MyController : Controller
{
[MyActionFilter]
public IActionResult MyAction()
{
// Логика действия контроллера
return Ok("Action executed");
}
}


Применение ко всему контроллеру
using Microsoft.AspNetCore.Mvc;

[MyActionFilter]
public class MyController : Controller
{
public IActionResult MyAction1()
{
// Логика действия контроллера
return Ok("Action 1 executed");
}

public IActionResult MyAction2()
{
// Логика действия контроллера
return Ok("Action 2 executed");
}
}


🟠Применение глобального фильтра
Фильтр также можно зарегистрировать глобально, чтобы он применялся ко всем контроллерам и действиям. Регистрация глобального фильтра в Startup.cs
using Microsoft.AspNetCore.Mvc;

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.Filters.Add<MyActionFilter>();
});
}


🚩Пример выполнения действий до и после запроса

Создание фильтра
using Microsoft.AspNetCore.Mvc.Filters;
using System;

public class LoggingActionFilter : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия контроллера
Console.WriteLine("Запрос начался: " + context.HttpContext.Request.Path);
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия контроллера
Console.WriteLine("Запрос завершился: " + context.HttpContext.Request.Path);
}
}


Применение фильтра к контроллеру
using Microsoft.AspNetCore.Mvc;

[LoggingActionFilter]
public class UsersController : Controller
{
public IActionResult GetUser(int id)
{
// Логика действия контроллера
return Ok(new { Id = id, Name = "User" + id });
}
}


Регистрация в Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Что такое сервис локатор?

Сервис-локатор — это паттерн проектирования, который предоставляет центральный реестр для поиска и получения экземпляров зависимостей или сервисов.
Класс сервис-локатора хранит ссылки на сервисы и позволяет запрашивать их по идентификатору, что упрощает управление зависимостями.
Однако этот паттерн критикуют за скрытые зависимости и нарушение принципа инверсии зависимостей (SOLID).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
🤔 Какие есть базовые сущности RabbitMQ?

Это популярный брокер сообщений, который используется для обмена сообщениями между различными компонентами системы. В RabbitMQ есть несколько базовых сущностей, которые нужно понимать для эффективного использования этой технологии.

🚩Базовые сущности

🟠Сообщения (Messages)
Это данные, которые отправляются от отправителя к получателю через RabbitMQ. Сообщения могут содержать любые данные: текст, JSON, XML, двоичные данные и т.д.

🟠Очереди (Queues)
Э
то места, где сообщения хранятся до тех пор, пока их не заберет получатель. Очереди обеспечивают надежную доставку сообщений и поддерживают множество получателей.
Создание очереди
rabbitmqadmin declare queue name=my_queue durable=true


🟠Обменники (Exchanges)
Принимают сообщения от отправителей и направляют их в соответствующие очереди на основе правил маршрутизации. Существует несколько типов обменников:
Direct: Сообщения направляются в очередь с ключом маршрутизации, точно соответствующим ключу, указанному в обменнике.
Fanout: Сообщения направляются во все очереди, связанные с этим обменником, без учета ключа маршрутизации.
Topic: Сообщения направляются в очереди на основе шаблонов ключей маршрутизации.
Headers: Сообщения направляются в очереди на основе соответствия заголовков.
Создание обменника:
rabbitmqadmin declare exchange name=my_exchange type=direct durable=true


🟠Связи (Bindings)
Определяют правила маршрутизации между обменниками и очередями. Они указывают, какие ключи маршрутизации должны использоваться для доставки сообщений из обменника в очередь.
Создание связи
rabbitmqadmin declare binding source=my_exchange destination=my_queue routing_key=my_key


🟠Ключи маршрутизации (Routing Keys)
Ключи маршрутизации используются обменниками для определения, в какие очереди направлять сообщения. Они играют ключевую роль при использовании direct и topic обменников.

🟠Потребители (Consumers)
Это приложения или службы, которые получают сообщения из очередей и обрабатывают их. Пример производителя на Python
import pika

def callback(ch, method, properties, body):
print(f"Received {body}")

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='my_queue')

channel.basic_consume(queue='my_queue', on_message_callback=callback, auto_ack=True)

print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()


🟠Производители (Producers)
Э
то приложения или службы, которые отправляют сообщения в обменники RabbitMQ. Пример производителя на Python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='my_queue')

channel.basic_publish(exchange='', routing_key='my_queue', body='Hello World!')

print(" [x] Sent 'Hello World!'")
connection.close()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31
🤔 Что такое get?

get — это метод или функция, используемая для получения значения из объекта, коллекции или свойства.
В языке Python, например, метод get применяется к словарям для безопасного извлечения значения по ключу, возвращая None или значение по умолчанию, если ключ отсутствует.
В JavaScript get может быть геттером, определяющим, как получить значение свойства объекта при его доступе.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4👾1
🤔 Расскажи про классификацию типов?

Типы данных можно классифицировать по нескольким критериям, включая базовые категории, такие как значимые типы (value types) и ссылочные типы (reference types), а также другие характеристики, такие как встроенные типы, пользовательские типы и системы типов.

🚩Классификации типов

🟠Значимые типы (Value Types)
Значимые типы хранят свои значения непосредственно и обычно располагаются в стеке. При присваивании переменной значимого типа другой переменной создается копия значения.
int a = 10;
int b = a; // b получит копию значения a


🟠Структуры (struct)
Пользовательские типы, которые объединяют несколько значений.
struct Point
{
public int X;
public int Y;
}

Point p1 = new Point { X = 1, Y = 2 };
Point p2 = p1; // p2 получит копию значений p1


🟠Перечисления (enum)
Типы, представляющие набор именованных констант.
enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
Days today = Days.Monday;


🟠Ссылочные типы (Reference Types)
Ссылочные типы хранят ссылки на объекты, которые располагаются в куче (heap). При присваивании переменной ссылочного типа другой переменной копируется ссылка на объект, а не сам объект.

🟠Классы (class)
Основные строительные блоки объектов.
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

Person p1 = new Person { Name = "Alice", Age = 30 };
Person p2 = p1; // p2 указывает на тот же объект, что и p1


🟠Интерфейсы (interface)
Контракты, определяющие набор методов и свойств, которые должны быть реализованы классами.
interface IAnimal
{
void Speak();
}

class Dog : IAnimal
{
public void Speak() => Console.WriteLine("Woof!");
}


🟠Делегаты (delegate)
Типы, представляющие ссылки на методы.
delegate void MyDelegate(string message);
MyDelegate del = Console.WriteLine;
del("Hello, World!");


🟠Массивы (arrays)
Коллекции элементов одного типа.
int[] numbers = new int[] { 1, 2, 3, 4, 5 };  


🟠Строки (string)
Последовательности символов.
string greeting = "Hello, World!";  


🟠Nullable типы
Nullable типы позволяют значимым типам принимать значение null, что означает отсутствие значения.
int? nullableInt = null;  


🟠Обобщенные типы (Generics)
Обобщенные типы позволяют создавать классы, методы и структуры, которые могут работать с любыми типами данных, обеспечивая типобезопасность и повторное использование кода.
class GenericClass<T>
{
public T Value { get; set; }
}

GenericClass<int> intInstance = new GenericClass<int> { Value = 10 };
GenericClass<string> stringInstance = new GenericClass<string> { Value = "Hello" };


🟠Неуправляемые типы (Unsafe Types)
Неуправляемые типы позволяют работать с указателями и выполнять низкоуровневые операции, которые обычно не разрешены в безопасном управляемом коде.
unsafe
{
int x = 10;
int* ptr = &x;
Console.WriteLine((int)ptr); // Вывод адреса переменной x
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍2
🤔 В чём разница абстрактного класса и интерфейса?

Абстрактный класс может содержать как реализацию методов, так и абстрактные методы, а интерфейс — только определения методов без реализации. Абстрактные классы могут иметь поля и конструкторы, а интерфейсы — нет. Класс может наследовать только один абстрактный класс, но реализовать несколько интерфейсов. Интерфейсы предоставляют более гибкий способ организации контракта для классов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚Базу Знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🤔 Где могут храниться значимые типы?

🚩Стек

Значимые типы обычно хранятся на стеке, когда они объявлены внутри метода. Это происходит потому, что стек обеспечивает быстрый доступ и автоматическое управление памятью.
void MyMethod()
{
int localVar = 10; // localVar хранится на стеке
}


🚩Куча

Значимые типы могут храниться в куче, если они являются частью объекта ссылочного типа. Например, если структура или переменная типа int является полем класса, то она будет храниться в куче вместе с объектом класса.
class MyClass
{
public int Number; // Number хранится в куче, потому что MyClass - ссылочный тип
}

MyClass obj = new MyClass();
obj.Number = 42;


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
🤔 Что такое ООП?

ООП (Объектно-Ориентированное Программирование) — это парадигма программирования, основанная на концепции объектов, которые объединяют данные и методы для их обработки. Основные принципы ООП включают инкапсуляцию, наследование, полиморфизм и абстракцию. ООП позволяет моделировать реальный мир с помощью классов и объектов, улучшая структуру и повторное использование кода. В C# все программы строятся на основе классов, что делает его строго объектно-ориентированным языком.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 Как хранить типы данных без unboxing`а?

Существует два способа избежать упаковки и распаковки (boxing и unboxing) значимых типов при их хранении в коллекциях или использовании в других ситуациях, где тип данных не должен быть упакован в объект.

🟠Использование обобщений (generics)
Обобщения позволяют создавать коллекции и методы, которые работают с любыми типами данных без необходимости упаковки.
// Пример использования обобщённого списка для значимого типа int
List<int> numbers = new List<int>();
numbers.Add(10); // Добавление без упаковки

int number = numbers[0]; // Чтение без распаковки


🟠Использование специальных структур
В некоторых случаях для избежания упаковки можно создать специальные структуры, которые содержат необходимые данные и методы.
// Обобщённый метод для работы с любыми типами данных без упаковки
public T FindMax<T>(T a, T b) where T : IComparable<T>
{
return a.CompareTo(b) > 0 ? a : b;
}

// Использование метода для значимого типа int
int max = FindMax(3, 5);
Console.WriteLine(max); // Выведет: 5


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51🤔1
🤔 Что такое стек?

Стек — это структура данных LIFO, где последний добавленный элемент извлекается первым, используется для вызовов функций и хранения локальных данных.
Чем отличается метод Equal от ==? Equals проверяет логическое равенство объектов, а == сравнивает ссылки для объектов и значения для примитивов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
🤔 Чем String отличается от других типов?

🟠Ссылочный тип
string является ссылочным типом, хотя по поведению он похож на значимый тип. Это означает, что переменная типа string содержит ссылку на объект строки, хранящийся в памяти, а не непосредственно данные.

🟠Иммутабельность (неизменяемость)
Объекты типа string неизменяемы. Это означает, что после создания строки её содержимое нельзя изменить. Любые операции, которые кажутся изменяющими строку (например, Replace, Substring), на самом деле создают новую строку.
string original = "Hello";
string modified = original.Replace('H', 'J'); // Создаётся новая строка "Jello"


🟠Поддержка операторов и методов
string поддерживает различные операторы и методы для работы с текстом. Например, оператор + для конкатенации строк, метод Substring для извлечения подстрок, метод Split для разбиения строки и т.д.
string hello = "Hello";
string world = "World";
string concatenated = hello + " " + world; // "Hello World"


🟠Интернирование строк
Для оптимизации памяти строки могут интернироваться. Это означает, что строки с одинаковым содержимым могут храниться в единственном экземпляре в пуле строк.
string a = "test";
string b = "test";
bool areEqual = object.ReferenceEquals(a, b); // True, потому что строки интернированы


🟠Специальная поддержка в языке
string имеет специальную поддержку на уровне языка. Например, строковые литералы в коде автоматически рассматриваются как объекты типа string.
string greeting = "Hello, world!";   


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8