C# | Вопросы собесов
5.1K subscribers
34 photos
1 file
980 links
Download Telegram
🤔 Что такое ООП?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
🤔 Как .NET 8 связан с async и await?

Включает в себя ряд улучшений и нововведений, связанных с асинхронным программированием, а именно с использованием ключевых слов async и await. Эти изменения направлены на повышение производительности и удобства использования асинхронных методов.

🟠Улучшенная производительность Task-based API
В .NET 8 были проведены оптимизации, которые улучшают производительность асинхронных операций. Это включает более эффективное управление задачами (Task), снижение накладных расходов на создание и завершение задач.

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

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

Асинхронные методы позволяют выполнять длительные операции, такие как ввод-вывод или сетевые запросы, без блокировки основного потока выполнения. Вот пример использования async и await:
using System;
using System.Net.Http;
using System.Threading.Tasks;

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

public static async Task<string> FetchDataAsync(string url)
{
using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string responseData = await response.Content.ReadAsStringAsync();
return responseData;
}
}
}


🚩Зачем нужны?

🟠Производительность
Оптимизация асинхронных операций позволяет приложениям обрабатывать большее количество запросов и задач за единицу времени, что особенно важно для серверных приложений и веб-сервисов.
🟠Удобство разработки
Улучшенные инструменты и библиотеки облегчают написание, отладку и мониторинг асинхронного кода, что делает разработку более продуктивной.
🟠Масштабируемость
Асинхронные операции позволяют приложениям лучше масштабироваться, эффективно распределяя ресурсы и минимизируя задержки.

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

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

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

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

🟠Обработка запросов
Middleware может перехватывать и изменять HTTP-запросы перед их передачей на основной сервер или конечную точку обработки.
🟠Обработка ответов
Middleware также может перехватывать и изменять HTTP-ответы перед их отправкой клиенту.
🟠Аутентификация и авторизация
Middleware может использоваться для проверки подлинности пользователей и определения их прав доступа.
🟠Логирование
Middleware может записывать информацию о запросах и ответах для целей мониторинга и отладки.
🟠Обработка ошибок
Middleware может перехватывать и обрабатывать ошибки, возникающие во время обработки запросов.
🟠Пример middleware в ASP.NET Core:
Мiddleware компоненты добавляются в конвейер обработки запросов через метод Configure в классе Startup.
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Пример простого middleware, который логирует каждый запрос
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});

// Добавление стандартного middleware для обработки статических файлов
app.UseStaticFiles();

// Добавление стандартного middleware для маршрутизации
app.UseRouting();

// Конечная точка обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}


🚩Зачем нужен?

🟠Разделение ответственности
Middleware позволяет разбивать обработку запросов на отдельные компоненты, каждый из которых отвечает за свою часть логики.
🟠Повторное использование кода
Один и тот же middleware может использоваться в разных частях приложения или даже в разных приложениях.
🟠Гибкость и расширяемость
Middleware можно легко добавлять, удалять или заменять, что упрощает модификацию и расширение приложения.
🟠Поддерживаемость
Разделение логики на отдельные компоненты делает код более структурированным и легким для поддержки.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔2🤯2👾2
🤔 Принципы ООП?

Основные принципы ООП включают инкапсуляцию, которая скрывает внутреннюю реализацию объекта и предоставляет доступ к данным через методы; наследование, которое позволяет создавать новые классы на основе существующих; полиморфизм, обеспечивающий возможность работы с объектами разных типов через общий интерфейс; и абстракцию, которая упрощает сложные системы, выделяя только ключевые характеристики объектов. Эти принципы делают код более структурированным и легко поддерживаемым.

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

Представляет собой последовательность компонентов middleware, через которые проходит HTTP-запрос, начиная с момента его получения сервером и до отправки ответа клиенту. Каждый компонент в конвейере выполняет определенные задачи, такие как аутентификация, авторизация, логирование, обработка ошибок и так далее. Конвейер позволяет легко управлять обработкой запросов, добавляя или удаляя компоненты middleware.

🚩Как работает

1⃣Получение запроса
Когда сервер получает HTTP-запрос, он передается в первый компонент middleware в конвейере.

2⃣Последовательная обработка
Запрос проходит через каждый компонент middleware последовательно.
Каждый компонент может:
Обрабатывать запрос и передать его следующему компоненту.
Обрабатывать запрос и завершить его обработку, не передавая дальше.
Внести изменения в запрос или ответ.

3⃣Передача управления
Компонент middleware может передать управление следующему компоненту, вызывая метод next.Invoke(). После завершения обработки запроса следующим компонентом, управление возвращается обратно к предыдущему компоненту.

4⃣Формирование ответа
Когда запрос доходит до конца конвейера и обработка завершается, ответ формируется и проходит обратно через все компоненты middleware в обратном порядке, что позволяет им вносить изменения в ответ перед его отправкой клиенту.

Настройка конвертатора обработки запросов в ASP.NET Core:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// Логирование запросов
app.Use(async (context, next) =>
{
Console.WriteLine($"Request: {context.Request.iss.onethod} {context.Request.Path}");
await next.Invoke();
Console.WriteLine($"Response: {context.Response.StatusCode}");
});

// Обработка статических файлов
app.UseStaticFiles();

// Маршрутизация
app.UseRouting();

// Аутентификация
app.UseAuthentication();

// Авторизация
app.UseAuthorization();

// Конечные точки обработки запросов
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
});
}
}


🚩Зачем нужен?

🟠Гибкость
Конвейер позволяет легко добавлять и удалять компоненты, изменяя способ обработки запросов.
🟠Модульность
Каждый компонент middleware выполняет свою задачу, что делает код более структурированным и легким для поддержки.
🟠Расширяемость
Можно легко добавить новые компоненты для обработки различных аспектов запросов, таких как кэширование, компрессия и другие.
🟠Повторное использование
Один и тот же компонент middleware может быть использован в разных приложениях, что снижает дублирование кода.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🤔 В чём разница между string и StringBuilder?

`string` в C# — это неизменяемый тип данных, что означает, что каждое изменение строки создаёт новый объект в памяти. `StringBuilder` — это изменяемый тип, который позволяет эффективно манипулировать строками без создания новых объектов, что улучшает производительность при частых изменениях строк. `StringBuilder` предпочтительнее использовать для конкатенации строк в циклах или при выполнении множества операций со строками. `string` лучше подходит для случаев, когда строка не меняется.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥5
🤔 Какие методы есть в Action фильтре?

Используются для выполнения логики до и после выполнения метода действия контроллера. Они предоставляют механизм для выполнения кросс-секционных задач, таких как логирование, обработка исключений, валидация и т.д. Action фильтры реализуют интерфейс IActionFilter или IAsyncActionFilter.

🚩Методы в Action фильтре

🟠OnActionExecuting
Этот метод вызывается перед выполнением метода действия. Здесь можно добавить логику, которая будет выполняться до вызова действия, например, логирование или проверка условий.
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
}


🟠OnActionExecuted
Этот метод вызывается после выполнения метода действия. Здесь можно добавить логику, которая будет выполняться после вызова действия, например, логирование результатов или модификация ответа.
public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
}


🟠OnActionExecutionAsync
Этот метод объединяет функциональность OnActionExecuting и OnActionExecuted в одном асинхронном методе. Здесь можно определить логику, которая будет выполняться как до, так и после выполнения метода действия.
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия

var resultContext = await next();

// Логика после выполнения действия
}


🚩Реализации Action фильтра

Синхронный Action фильтр:
public class SampleActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");
}

public void OnActionExecuted(ActionExecutedContext context)
{
// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


Асинхронный Action фильтр:
public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Логика до выполнения действия
Console.WriteLine("Before executing action");

var resultContext = await next();

// Логика после выполнения действия
Console.WriteLine("After executing action");
}
}


🚩Применение Action фильтра

Action фильтр можно применять к контроллерам или действиям контроллера с помощью атрибута [ServiceFilter] или [TypeFilter]. Также его можно зарегистрировать глобально в Startup.cs.

Применение к контроллеру или действию:
[ServiceFilter(typeof(SampleActionFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}


Глобальная регистрация:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config =>
{
config.Filters.Add(typeof(SampleActionFilter));
});
}


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

`async` и `await` — это ключевые слова в C#, которые используются для работы с асинхронным кодом. `async` обозначает метод как асинхронный, а `await` позволяет приостановить выполнение метода до завершения асинхронной операции, не блокируя основной поток. Это позволяет писать асинхронный код, который выглядит как синхронный, улучшая читаемость и производительность программ. Асинхронные операции полезны для выполнения долгих задач, таких как запросы к базе данных или сети.

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

Определяет, как сообщения от производителей (producers) направляются в очереди через обменники (exchanges).

1⃣Producers (Производители)
Отправляют сообщения в обменники.

2⃣Exchanges (Обменники)
Направляют сообщения в очереди на основе привязок (bindings) и типа обменника:
Direct Exchange: Сообщения направляются в очереди, соответствующие точному ключу маршрутизации.
Topic Exchange: Направляет сообщения в очереди по шаблону ключа маршрутизации.
Fanout Exchange: Широковещательно отправляет сообщения во все очереди, связанные с обменником.
Headers Exchange: Использует заголовки сообщений для маршрутизации.

3⃣Queues (Очереди)
Получают сообщения от обменников.

4⃣Bindings (Привязки)
Связывают обменники с очередями и определяют правила маршрутизации.

🚩Пример настройки

1⃣Объявление обменника и очереди
import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')

connection.close()


2⃣Отправка сообщения
import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
routing_key = 'info'
message = 'Hello, RabbitMQ!'
channel.basic_publish(exchange='direct_logs', routing_key=routing_key, body=message)

connection.close()


3⃣Получение сообщений
import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.iss.onethod.queue
channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key='info')

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

channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
print('Waiting for messages. To exit press CTRL+C')
channel.start_consuming()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁7👍1
🤔 Что умеет Action фильтр?

Action фильтр в ASP.NET позволяет выполнять дополнительную логику до и после выполнения действий контроллера. Он может использоваться для задач, таких как валидация входных данных, логирование, аутентификация или изменение результата выполнения действия. Фильтры упрощают повторное использование кода и делают обработку запросов более гибкой и расширяемой. Action фильтры можно применять ко всем действиям контроллера или только к определённым методам.

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

🟠Direct
Сообщения направляются в очереди, которые связаны с обменником, если ключ маршрутизации сообщения точно совпадает с ключом маршрутизации, указанным в привязке. Логирование сообщений с разными уровнями важности, где каждая очередь получает сообщения с определенным уровнем (например, "info", "warning", "error").
channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");


🟠Topic
Сообщения направляются в очереди на основе шаблонов ключей маршрутизации. Поддерживаются подстановочные знаки: * (заменяет одно слово) и # (заменяет ноль или более слов). Маршрутизация сообщений в зависимости от нескольких критериев, например, "logs.error", "logs.info.user".
channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");


🟠Fanout
Широковещательно отправляет сообщения во все очереди, связанные с этим обменником, игнорируя ключ маршрутизации. Широковещательная рассылка сообщений всем подписчикам, например, рассылка уведомлений.
channel.ExchangeDeclare(exchange: "logs", type: "fanout");


🟠Headers
Направляет сообщения в очереди на основе заголовков сообщений, а не ключей маршрутизации. Можно задавать правила маршрутизации с использованием заголовков. Маршрутизация сообщений на основе различных свойств, таких как content-type или любые другие произвольные атрибуты.
channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");


🚩Пример настройки обменников и привязок

Direct
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: "info");

connection.Close();


Topic
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "topic_logs", routingKey: "logs.*.user");

connection.Close();


Fanout
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "logs", type: "fanout");
var queueName = channel.QueueDeclare().QueueName;

channel.QueueBind(queue: queueName, exchange: "logs", routingKey: "");

connection.Close();


Headers
using RabbitMQ.Client;

var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();

channel.ExchangeDeclare(exchange: "headers_logs", type: "headers");
var queueName = channel.QueueDeclare().QueueName;

var headers = new Dictionary<string, object>
{
{ "x-match", "all" },
{ "key1", "value1" },
{ "key2", "value2" }
};

channel.QueueBind(queue: queueName, exchange: "headers_logs", routingKey: "", arguments: headers);


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

`IEnumerable` используется для перебора коллекции в памяти и поддерживает ленивую загрузку данных. `IQueryable` позволяет работать с данными на уровне источника данных, поддерживая отложенное выполнение запросов и возможность составления SQL-запросов для баз данных. `IQueryable` чаще используется в LINQ для работы с базами данных, а `IEnumerable` — для работы с коллекциями, уже загруженными в память. `IQueryable` может оптимизировать запросы, выполняя их на сервере базы данных.

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

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

🚩Особенности

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

🟠Поддержка различных типов данных
Строки (Strings): Самый простой тип данных в Redis, который может содержать текст или двоичные данные.
Списки (Lists): Упорядоченные коллекции строк, которые можно использовать как очереди или стеки.
Множества (Sets): Неупорядоченные коллекции уникальных строк.
Упорядоченные множества (Sorted Sets): Коллекции уникальных строк, каждая из которых связана с числовым значением (score), определяющим порядок.
Хеши (Hashes): Коллекции пар "ключ-значение", где каждый хеш связан с ключом.
Bitmaps и HyperLogLogs: Для эффективного хранения и обработки больших объемов данных.

🟠Высокая производительность
Благодаря хранению данных в памяти и простому протоколу клиент-сервер, Redis обеспечивает очень высокую скорость операций.

🟠Поддержка репликации
Redis поддерживает мастер-слейв репликацию, что позволяет создать резервные копии данных и обеспечить отказоустойчивость.

🟠Кластеризация
Redis Cluster позволяет распределить данные по нескольким узлам, обеспечивая горизонтальную масштабируемость.

🟠Поддержка Lua-скриптов
Redis позволяет выполнять атомарные операции с помощью Lua-скриптов.

🟠Транзакции
Redis поддерживает транзакции, позволяя выполнить несколько команд атомарно.

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

🟠Кэширование
Redis часто используется для кэширования данных, что позволяет значительно уменьшить задержку доступа и снизить нагрузку на базу данных.
using StackExchange.Redis;
using System;

class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();

db.StringSet("key", "value");
string value = db.StringGet("key");

Console.WriteLine(value);
}
}


🟠Сессии
Хранение сессий пользователя для веб-приложений, что обеспечивает быстрое и эффективное управление состоянием.

🟠Очереди сообщений
Использование списков или упорядоченных множеств для организации очередей сообщений.
using StackExchange.Redis;
using System;

class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();

db.ListLeftPush("queue", "task1");
db.ListLeftPush("queue", "task2");

string task = db.ListRightPop("queue");
Console.WriteLine(task);
}
}


🟠Счетчики и рейтинги
Использование упорядоченных множеств для реализации счетчиков, рейтингов или систем рекомендаций.
using StackExchange.Redis;
using System;

class Program
{
static void Main()
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();

// Add scores for users
db.SortedSetAdd("scores", "user1", 100);
db.SortedSetAdd("scores", "user2", 200);

// Retrieve scores with scores included
var scores = db.SortedSetRangeByRankWithScores("scores", 0, -1);

foreach (var score in scores)
{
Console.WriteLine($"{score.Element}: {score.Score}");
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🤔 Зачем нужны интерфейсы, если есть абстрактные классы?

Интерфейсы в C# позволяют определять набор методов, которые должны быть реализованы в классах, но не содержат реализации. В отличие от абстрактных классов, интерфейсы не могут содержать полей или реализаций методов (до C# 8.0), и класс может реализовать несколько интерфейсов, но наследовать только один абстрактный класс. Интерфейсы используются для создания гибких архитектур, когда классы могут реализовать множество интерфейсов, предоставляя различные поведения. Они помогают достигать полиморфизма и создавать легко тестируемые системы.

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

Это система кэширования, которая использует два различных уровня хранения данных для повышения производительности и обеспечения надежности. Такая система обычно включает более быстрый, но меньший по объему кеш первого уровня (L1) и более медленный, но более объемный кеш второго уровня (L2). Двухуровневое кэширование часто используется для улучшения времени доступа к данным и оптимизации использования ресурсов.

🚩Принципы

🟠Кеш первого уровня (L1)
Характеристики: Высокая скорость доступа, меньший объем.
Типичные реализации: В памяти (например, локальный кеш на уровне приложения или узла).
Использование: Содержит наиболее часто используемые данные для быстрого доступа.

🟠Кеш второго уровня (L2)
Характеристики: Медленнее, чем L1, но обладает большим объемом.
Типичные реализации: Внешние системы хранения данных (например, распределенные кеши или базы данных в памяти, такие как Redis).
Использование: Содержит данные, которые не поместились в L1 или которые используются реже.

🚩Пример двухуровневого кеша

1⃣Настройка локального кеша (L1)
var l1Cache = new L1Cache(100);
l1Cache.Set("myKey", "myValue");
var value = l1Cache.Get<string, string>("myKey");


2⃣Настройка удаленного кеша (L2) с использованием Redis
var redisCache = new RedisCache();
redisCache.Set("myKey", "myValue");
var value = redisCache.Get("myKey");


3⃣Реализация двухуровневого кеша
using System;
using Microsoft.Extensions.Caching.Memory;
using StackExchange.Redis;

public class CacheService
{
private readonly MemoryCache _l1Cache;
private readonly IDatabase _l2Cache;

public CacheService(int l1CacheSize, string redisHost = "localhost", int redisPort = 6379, int redisDb = 0)
{
_l1Cache = new MemoryCache(new MemoryCacheOptions { SizeLimit = l1CacheSize });
var redis = ConnectionMultiplexer.Connect($"{redisHost}:{redisPort}");
_l2Cache = redis.GetDatabase(redisDb);
}

public string GetData(string key)
{
// Проверка в кеше L1
if (_l1Cache.TryGetValue(key, out string l1Value))
{
Console.WriteLine("L1 Cache Hit");
return l1Value;
}

// Проверка в кеше L2 (Redis)
var l2Value = _l2Cache.StringGet(key);
if (l2Value.HasValue)
{
Console.WriteLine("L2 Cache Hit");
_l1Cache.Set(key, l2Value, new MemoryCacheEntryOptions().SetSize(1));
return l2Value;
}

// Если данные не найдены, получение из исходного хранилища
Console.WriteLine("Cache Miss");
var dbValue = GetDataFromDatabase(key);

// Добавление данных в оба кеша
_l1Cache.Set(key, dbValue, new MemoryCacheEntryOptions().SetSize(1));
_l2Cache.StringSet(key, dbValue);

return dbValue;
}

private string GetDataFromDatabase(string key)
{
// Симуляция получения данных из базы данных
return $"Data for {key}";
}
}


🚩Плюсы

Увеличенная производительность
Быстрый доступ к часто используемым данным через L1, при этом L2 обеспечивает хранение большого объема данных.
Оптимизация ресурсов
Сбалансированное использование памяти и внешних хранилищ для кэширования.
Надежность
Разделение кеша на уровни позволяет сохранить доступность данных при отказе одного из уровней.

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

Многопоточность — это возможность выполнения нескольких потоков (threads) одновременно в одной программе. В C# многопоточность поддерживается с помощью класса `Thread`, задач (`Task`) и `ThreadPool`. Многопоточность используется для выполнения параллельных операций, таких как обработка данных или выполнение задач, которые не должны блокировать основной поток. Она помогает повысить производительность, но требует осторожности для предотвращения гонок данных и взаимоблокировок.

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

Это технология, обеспечивающая двустороннюю связь между клиентом и сервером через один TCP-соединение. В отличие от традиционного HTTP, который работает по принципу запрос-ответ, WebSockets позволяют передавать данные в обоих направлениях в режиме реального времени, что делает их идеальными для приложений, требующих мгновенного обмена данными.

🚩Характеристики

🟠Двусторонняя связь
Клиент и сервер могут отправлять данные друг другу независимо, без необходимости инициировать новый запрос.

🟠Постоянное соединение
После установления WebSocket-соединение остается открытым, что позволяет передавать данные с минимальной задержкой.

🟠Эффективность
Меньшие накладные расходы по сравнению с HTTP, так как заголовки передаются только при установлении соединения, а не для каждого сообщения.

🟠Масштабируемость
Поддержка большого количества одновременных соединений, что полезно для чатов, игр и других приложений с интенсивным обменом данными.

🚩Как работают

1⃣Установка соединения
Клиент инициирует соединение с сервером через HTTP-запрос с заголовком Upgrade, указывая, что он хочет перейти на WebSocket-протокол.
2⃣Рукопожатие (handshake)
Сервер отвечает согласием на переход на WebSocket-протокол, и соединение устанавливается.
3⃣Обмен данными
После установления соединения данные могут передаваться в обоих направлениях до тех пор, пока одно из сторон не закроет соединение.

🚩Пример использования

Сервер на Python с использованием библиотеки websockets
import asyncio
import websockets

async def handler(websocket, path):
async for message in websocket:
print(f"Received message: {message}")
await websocket.send(f"Echo: {message}")

start_server = websockets.serve(handler, "localhost", 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()


Клиент на JavaScript
const socket = new WebSocket('ws://localhost:8765');

socket.onopen = function(event) {
console.log('WebSocket is open now.');
socket.send('Hello, Server!');
};

socket.onmessage = function(event) {
console.log(`Message from server: ${event.data}`);
};

socket.onclose = function(event) {
console.log('WebSocket is closed now.');
};

socket.onerror = function(error) {
console.log(`WebSocket error: ${error}`);
};


🚩Плюсы

Реальное время
Подходит для приложений, где важна минимальная задержка, таких как чаты, игровые приложения и финансовые торговые платформы.
Меньшие накладные расходы
Меньшее количество данных передается по сети по сравнению с традиционными HTTP-запросами.
Удобство
Простота в использовании и поддержка большинством современных браузеров.

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

`Boxing` — это процесс преобразования значимого типа (например, int) в объект, чтобы хранить его в виде ссылочного типа. `Unboxing` — это обратный процесс преобразования объекта обратно в значимый тип. Эти операции создают накладные расходы на память и процессор, так как требуют размещения объектов в куче. Boxing и unboxing следует минимизировать для повышения производительности, особенно в критически важных местах программы.

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

В веб-разработке бекенд и фронтенд взаимодействуют друг с другом, чтобы создать полноценное веб-приложение. Бекенд — это серверная часть приложения, которая отвечает за обработку данных, выполнение бизнес-логики и взаимодействие с базой данных. Фронтенд — это клиентская часть, которая отвечает за отображение данных и взаимодействие с пользователем. Связь между ними осуществляется через API (Application Programming Interface).

🟠Архитектура клиент-сервер
Веб-приложения обычно строятся на основе архитектуры клиент-сервер:
Клиент (фронтенд): Браузер или мобильное приложение, которое пользователь видит и с которым взаимодействует.
Сервер (бекенд): Серверное приложение, которое обрабатывает запросы от клиента, выполняет бизнес-логику и возвращает ответы.

🟠Протокол HTTP/HTTPS
Фронтенд и бекенд взаимодействуют по протоколу HTTP (или HTTPS для защищенных соединений). Когда пользователь совершает действие на фронтенде (например, нажимает кнопку или заполняет форму), фронтенд отправляет HTTP-запрос на сервер.

🟠API (REST, GraphQL)
Для взаимодействия между фронтендом и бекендом часто используют API:
REST (Representational State Transfer): Стандартный способ создания API, который использует HTTP-методы (GET, POST, PUT, DELETE) для взаимодействия с ресурсами на сервере.
GraphQL: Альтернатива REST, позволяющая клиенту запрашивать именно те данные, которые ему нужны.

Пример REST-запроса
// Пример контроллера на C# (ASP.NET Core)
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
[HttpGet]
public IActionResult GetProducts()
{
var products = _productService.GetAllProducts();
return Ok(products);
}

[HttpPost]
public IActionResult CreateProduct(Product product)
{
_productService.AddProduct(product);
return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
}

[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
var product = _productService.GetProductById(id);
if (product == null)
{
return NotFound();
}
return Ok(product);
}
}


🟠Обмен данными (JSON, XML)
Фронтенд и бекенд обмениваются данными в формате JSON или XML. JSON чаще используется из-за его простоты и легкости интеграции с JavaScript.

Пример JSON-ответа
[
{
"id": 1,
"name": "Product A",
"price": 100.0
},
{
"id": 2,
"name": "Product B",
"price": 150.0
}
]


🟠Запросы и ответы
Фронтенд отправляет запросы к бекенду с помощью библиотеки (например, fetch или axios в JavaScript)
// Пример использования fetch для отправки запроса
fetch('https://example.com/api/products')
.then(response => response.json())
.then(data => console.log(data));


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