🤔 Что такое метод Finalize?
Метод Finalize() представляет собой специальный метод, который предназначен для выполнения финальной очистки ресурсов перед тем, как объект будет уничтожен сборщиком мусора. Это метод, который может быть определен в классе для очистки неуправляемых ресурсов, если класс не реализует интерфейс
🚩Особенности метода
🟠Автоматический вызов
Сборщик мусора автоматически вызывает
🟠Определение в базовом классе `Object`
Все объекты наследуют от базового класса
🟠Замедление сборки мусора
Наличие объектов с финализаторами может замедлить процесс сборки мусора, так как объекты, требующие финализации, должны быть обработаны дважды: сначала они помещаются в очередь финализации, а затем их память освобождается после выполнения
Ставь 👍 и забирай 📚 Базу знаний
Метод Finalize() представляет собой специальный метод, который предназначен для выполнения финальной очистки ресурсов перед тем, как объект будет уничтожен сборщиком мусора. Это метод, который может быть определен в классе для очистки неуправляемых ресурсов, если класс не реализует интерфейс
IDisposable.🚩Особенности метода
🟠Автоматический вызов
Сборщик мусора автоматически вызывает
Finalize() на объекте, который не имеет других активных ссылок и который определяет финализатор. Это происходит непосредственно перед тем, как сборщик мусора освобождает память, занимаемую объектом.🟠Определение в базовом классе `Object`
Все объекты наследуют от базового класса
Object, который предоставляет реализацию Finalize(). Однако в большинстве случаев Finalize() не имеет реализации и не делает ничего, пока не будет переопределен в производном классе.🟠Замедление сборки мусора
Наличие объектов с финализаторами может замедлить процесс сборки мусора, так как объекты, требующие финализации, должны быть обработаны дважды: сначала они помещаются в очередь финализации, а затем их память освобождается после выполнения
Finalize().class ResourceWrapper
{
// Конструктор
public ResourceWrapper() {
// Инициализация ресурсов
}
// Финализатор
~ResourceWrapper() {
// Код очистки ресурсов
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Какие проблемы могут быть при многопоточности и как их избежать?
Проблемы: состояния гонки, deadlock, livelock, взаимные блокировки и неправильная синхронизация данных. Их избегают с помощью использования примитивов синхронизации (например, lock, Monitor, Mutex), разделения ответственности между потоками, атомарных операций и минимизации общего доступа к ресурсам.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥2👍1
🤔 Что такое В3 индекс?
Это структура данных, используемая в системах управления базами данных (СУБД) для организации и ускорения доступа к данным. B-tree индекс является сбалансированным деревом, обеспечивающим эффективное выполнение операций поиска, вставки, удаления и диапазонного поиска. B-tree индекс используется большинством реляционных СУБД, таких как SQL Server, MySQL, PostgreSQL и Oracle.
🚩Основные характеристики B-tree индекса
🟠Сбалансированное дерево
B-tree индекс является сбалансированным деревом, где все листья находятся на одном уровне. Это обеспечивает равномерное время доступа к данным.
🟠Ключи и значения
В узлах B-tree хранятся ключи, которые могут ссылаться на строки в таблице или на другие узлы дерева.
🟠Упорядоченность
Ключи в каждом узле упорядочены, что позволяет эффективно выполнять бинарный поиск внутри узла.
🟠Диапазонные запросы
B-tree индекс эффективно поддерживает диапазонные запросы (например, поиск всех записей с ключами между заданными значениями).
🟠Динамическое поддержание
B-tree автоматически сбалансирован, что позволяет эффективно выполнять операции вставки, удаления и обновления.
🚩Пример использования
🚩Операции
🟠Поиск
Операция поиска в B-tree выполняется за логарифмическое время O(log n), где n — количество узлов.
🟠Диапазонный поиск
Диапазонные запросы, такие как поиск всех сотрудников с фамилией от 'A' до 'M', выполняются эффективно.
🟠Вставка
При вставке новой записи в таблицу с индексом B-tree, запись добавляется в соответствующее место, поддерживая балансировку дерева.
🟠Удаление
При удалении записи соответствующий ключ удаляется из B-tree, и дерево автоматически перестраивается, чтобы сохранить балансировку.
🚩Плюсы
➕Быстрый доступ
Обеспечивает быстрый доступ к данным благодаря сбалансированной структуре дерева.
➕Эффективная работа с большими объемами данных
Поддерживает операции вставки, удаления и поиска с логарифмической сложностью.
➕Поддержка диапазонных запросов
Эффективно обрабатывает диапазонные запросы благодаря упорядоченной структуре.
➕Автоматическая балансировка
Динамическая балансировка дерева обеспечивает равномерное время доступа и вставки/удаления.
🚩Минусы
➖Использование ресурсов
Требует дополнительного пространства для хранения структуры дерева и ключей.
➖Затраты на поддержание
Вставка и удаление могут требовать перестроения узлов, что влечет за собой дополнительные вычислительные затраты.
➖Фрагментация
При частых операциях вставки и удаления может возникнуть фрагментация, что может потребовать периодического обслуживания (например, реорганизации индекса).
Ставь 👍 и забирай 📚 Базу знаний
Это структура данных, используемая в системах управления базами данных (СУБД) для организации и ускорения доступа к данным. B-tree индекс является сбалансированным деревом, обеспечивающим эффективное выполнение операций поиска, вставки, удаления и диапазонного поиска. B-tree индекс используется большинством реляционных СУБД, таких как SQL Server, MySQL, PostgreSQL и Oracle.
🚩Основные характеристики B-tree индекса
🟠Сбалансированное дерево
B-tree индекс является сбалансированным деревом, где все листья находятся на одном уровне. Это обеспечивает равномерное время доступа к данным.
🟠Ключи и значения
В узлах B-tree хранятся ключи, которые могут ссылаться на строки в таблице или на другие узлы дерева.
🟠Упорядоченность
Ключи в каждом узле упорядочены, что позволяет эффективно выполнять бинарный поиск внутри узла.
🟠Диапазонные запросы
B-tree индекс эффективно поддерживает диапазонные запросы (например, поиск всех записей с ключами между заданными значениями).
🟠Динамическое поддержание
B-tree автоматически сбалансирован, что позволяет эффективно выполнять операции вставки, удаления и обновления.
🚩Пример использования
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
DepartmentID INT,
Salary DECIMAL(10, 2)
);
CREATE INDEX idx_lastname ON Employees(LastName);
🚩Операции
🟠Поиск
Операция поиска в B-tree выполняется за логарифмическое время O(log n), где n — количество узлов.
SELECT * FROM Employees WHERE LastName = 'Smith';
🟠Диапазонный поиск
Диапазонные запросы, такие как поиск всех сотрудников с фамилией от 'A' до 'M', выполняются эффективно.
SELECT * FROM Employees WHERE LastName BETWEEN 'A' AND 'M';
🟠Вставка
При вставке новой записи в таблицу с индексом B-tree, запись добавляется в соответствующее место, поддерживая балансировку дерева.
INSERT INTO Employees (EmployeeID, FirstName, LastName, DepartmentID, Salary)
VALUES (1, 'John', 'Doe', 10, 60000.00);
🟠Удаление
При удалении записи соответствующий ключ удаляется из B-tree, и дерево автоматически перестраивается, чтобы сохранить балансировку.
DELETE FROM Employees WHERE EmployeeID = 1;
🚩Плюсы
➕Быстрый доступ
Обеспечивает быстрый доступ к данным благодаря сбалансированной структуре дерева.
➕Эффективная работа с большими объемами данных
Поддерживает операции вставки, удаления и поиска с логарифмической сложностью.
➕Поддержка диапазонных запросов
Эффективно обрабатывает диапазонные запросы благодаря упорядоченной структуре.
➕Автоматическая балансировка
Динамическая балансировка дерева обеспечивает равномерное время доступа и вставки/удаления.
🚩Минусы
➖Использование ресурсов
Требует дополнительного пространства для хранения структуры дерева и ключей.
➖Затраты на поддержание
Вставка и удаление могут требовать перестроения узлов, что влечет за собой дополнительные вычислительные затраты.
➖Фрагментация
При частых операциях вставки и удаления может возникнуть фрагментация, что может потребовать периодического обслуживания (например, реорганизации индекса).
Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 В какой момент отправляется запрос к базе данных?
Запрос отправляется к базе данных, когда приложение вызывает операции, такие как SaveChanges (в ORM) или выполняет SQL-команду напрямую.
1. В ORM запрос может быть отложен до реального использования данных (ленивая загрузка).
2. Это позволяет оптимизировать взаимодействие с базой, минимизируя количество запросов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Запрос отправляется к базе данных, когда приложение вызывает операции, такие как SaveChanges (в ORM) или выполняет SQL-команду напрямую.
1. В ORM запрос может быть отложен до реального использования данных (ленивая загрузка).
2. Это позволяет оптимизировать взаимодействие с базой, минимизируя количество запросов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔 В чем суть extension методов?
Extension-методы (методы расширения) — это способ добавить новые методы к существующим классам, не изменяя их код и не создавая наследников. Они позволяют расширять классы и интерфейсы, даже если у нас нет доступа к их исходному коду.
🚩Как работают extension-методы?
Это обычные статические методы, но объявленные внутри статического класса.
Первый параметр метода должен принимать тот тип, который мы хотим расширить, и перед ним ставится ключевое слово
После этого метод становится доступен как "встроенный" у этого типа.
🟠Добавляем метод к `string`
Допустим, у нас есть строка, и мы хотим добавить метод
🟠Расширяем `List<int>`
Добавим метод `SumEvenNumbers()`, который суммирует только четные числа в
🚩Когда использовать extension-методы?
Когда нужно добавить новый метод к существующему классу, но нельзя изменить его код (например,
Когда хочется сделать код более читаемым:
Когда нужно улучшить API без наследования и изменения структуры классов.
Ставь 👍 и забирай 📚 Базу знаний
Extension-методы (методы расширения) — это способ добавить новые методы к существующим классам, не изменяя их код и не создавая наследников. Они позволяют расширять классы и интерфейсы, даже если у нас нет доступа к их исходному коду.
🚩Как работают extension-методы?
Это обычные статические методы, но объявленные внутри статического класса.
Первый параметр метода должен принимать тот тип, который мы хотим расширить, и перед ним ставится ключевое слово
this. После этого метод становится доступен как "встроенный" у этого типа.
🟠Добавляем метод к `string`
Допустим, у нас есть строка, и мы хотим добавить метод
ToSnakeCase, который заменяет пробелы на нижние подчеркивания. using System;
public static class StringExtensions
{
public static string ToSnakeCase(this string str)
{
return str.Replace(" ", "_").ToLower();
}
}
class Program
{
static void Main()
{
string text = "Hello World";
Console.WriteLine(text.ToSnakeCase()); // hello_world
}
}
🟠Расширяем `List<int>`
Добавим метод `SumEvenNumbers()`, который суммирует только четные числа в
List<int>. using System;
using System.Collections.Generic;
using System.Linq;
public static class ListExtensions
{
public static int SumEvenNumbers(this List<int> numbers)
{
return numbers.Where(n => n % 2 == 0).Sum();
}
}
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
Console.WriteLine(numbers.SumEvenNumbers()); // 12 (2 + 4 + 6)
}
}
🚩Когда использовать extension-методы?
Когда нужно добавить новый метод к существующему классу, но нельзя изменить его код (например,
string, List<T>, DateTime). Когда хочется сделать код более читаемым:
numbers.SumEvenNumbers() лучше, чем MyExtensions.SumEvenNumbers(numbers). Когда нужно улучшить API без наследования и изменения структуры классов.
Ставь 👍 и забирай 📚 Базу знаний
👍2🔥1
🤔 Какие есть структуры данных?
- Линейные: массивы, списки, стеки, очереди.
- Связные: односвязные, двусвязные списки.
- Хеш-таблицы: Dictionary, HashMap.
- Деревья: бинарные, AVL, красно-чёрные.
- Графы: ориентированные, неориентированные.
- Кучи, матрицы, множества, деки, очереди с приоритетом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Линейные: массивы, списки, стеки, очереди.
- Связные: односвязные, двусвязные списки.
- Хеш-таблицы: Dictionary, HashMap.
- Деревья: бинарные, AVL, красно-чёрные.
- Графы: ориентированные, неориентированные.
- Кучи, матрицы, множества, деки, очереди с приоритетом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥6👍1
🤔 Если в двух переменных хранится одинаковое значение, то будут ли они равны?
Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.
🟠Примитивные типы (Value Types)
Для примитивных типов (например,
🟠Ссылочные типы (Reference Types)
Для ссылочных типов (например, классы, строки) переменные содержат ссылки на объекты в куче. Сравнение ссылочных типов по умолчанию выполняется по ссылке, а не по значению.
🟠Строки (Strings)
Строки являются ссылочными типами, но переопределяют операторы сравнения
🟠Кастомные классы
Для кастомных классов можно переопределить методы
Ставь 👍 и забирай 📚 Базу знаний
Сравнение значений переменных может зависеть от типа данных, хранящихся в этих переменных, и от способа их сравнения.
🟠Примитивные типы (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
Ставь 👍 и забирай 📚 Базу знаний
🤔 Что такое EF?
Entity Framework (EF) — это ORM (Object-Relational Mapping) фреймворк от Microsoft, который позволяет разработчикам работать с данными как с объектами, не беспокоясь о базовых SQL запросах. Это упрощает работу с базами данных, автоматически обрабатывая запросы, обновления и связи данных. EF поддерживает широкий спектр функциональности баз данных и облегчает интеграцию данных в .NET-приложения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4
🤔 Какие тесты бывают?
🚩Виды
🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: xUnit, NUnit, MSTest.
🟠Интеграционные тесты
Проверяют взаимодействие между различными компонентами системы, убеждаясь, что они корректно работают вместе.
Цель: Проверка взаимодействия между модулями.
Инструменты: xUnit, NUnit, MSTest, плюс дополнительные библиотеки для тестирования баз данных или HTTP-запросов.
🟠Функциональные тесты
Проверяют, что приложение выполняет свои функции в соответствии с требованиями. Эти тесты проверяют конкретные сценарии использования.
Цель: Проверка функциональности приложения на уровне пользователя.
Инструменты: Selenium, Playwright, Cypress.
🟠Системные тесты
Проверяют приложение в целом, включая взаимодействие с внешними системами и проверку всех требований.
Цель: Проверка всей системы в интегрированном виде.
Инструменты: JUnit, TestNG для Java, или те же инструменты, что и для функциональных тестов.
🟠Приемочные тесты
Проводятся для проверки, что приложение соответствует требованиям и готово к использованию клиентом или конечным пользователем.
Цель: Подтверждение соответствия приложения требованиям.
Инструменты: Cucumber, SpecFlow (для BDD).
🟠Регрессионные тесты
Проверяют, что недавние изменения в коде не нарушили существующую функциональность.
Цель: Убедиться, что новые изменения не привели к новым багам.
Инструменты: Все инструменты для юнит-тестирования и функционального тестирования.
🟠Нагрузочные тесты
Проверяют, как приложение ведет себя под нагрузкой, например, при большом количестве одновременных пользователей или операций.
Цель: Оценка производительности и устойчивости приложения под нагрузкой.
Инструменты: JMeter, Gatling, Apache Bench.
Ставь 👍 и забирай 📚 Базу знаний
🚩Виды
🟠Юнит-тесты
Предназначены для проверки отдельных компонентов или модулей приложения в изоляции. Они помогают убедиться, что отдельные функции или методы работают правильно.
Цель: Проверка логики отдельных методов или классов.
Инструменты: xUnit, NUnit, MSTest.
using Xunit;
public class CalculatorTests
{
[Fact]
public void Add_SimpleValues_ReturnsSum()
{
var calculator = new Calculator();
var result = calculator.Add(2, 3);
Assert.Equal(5, result);
}
}
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
}
🟠Интеграционные тесты
Проверяют взаимодействие между различными компонентами системы, убеждаясь, что они корректно работают вместе.
Цель: Проверка взаимодействия между модулями.
Инструменты: xUnit, NUnit, MSTest, плюс дополнительные библиотеки для тестирования баз данных или HTTP-запросов.
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
public class IntegrationTests
{
private readonly HttpClient _client;
public IntegrationTests()
{
var appFactory = new CustomWebApplicationFactory<Startup>();
_client = appFactory.CreateClient();
}
[Fact]
public async Task Get_EndpointReturnsSuccessAndCorrectContentType()
{
var response = await _client.GetAsync("/api/values");
response.EnsureSuccessStatusCode();
Assert.Equal("application/json; charset=utf-8", response.Content.Headers.ContentType.ToString());
}
}
🟠Функциональные тесты
Проверяют, что приложение выполняет свои функции в соответствии с требованиями. Эти тесты проверяют конкретные сценарии использования.
Цель: Проверка функциональности приложения на уровне пользователя.
Инструменты: Selenium, Playwright, Cypress.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Xunit;
public class UiTests
{
[Fact]
public void LoadPage_CheckTitle()
{
using (IWebDriver driver = new ChromeDriver())
{
driver.Navigate().GoToUrl("https://example.com");
Assert.Equal("Example Domain", driver.Title);
}
}
}
🟠Системные тесты
Проверяют приложение в целом, включая взаимодействие с внешними системами и проверку всех требований.
Цель: Проверка всей системы в интегрированном виде.
Инструменты: JUnit, TestNG для Java, или те же инструменты, что и для функциональных тестов.
🟠Приемочные тесты
Проводятся для проверки, что приложение соответствует требованиям и готово к использованию клиентом или конечным пользователем.
Цель: Подтверждение соответствия приложения требованиям.
Инструменты: Cucumber, SpecFlow (для BDD).
🟠Регрессионные тесты
Проверяют, что недавние изменения в коде не нарушили существующую функциональность.
Цель: Убедиться, что новые изменения не привели к новым багам.
Инструменты: Все инструменты для юнит-тестирования и функционального тестирования.
🟠Нагрузочные тесты
Проверяют, как приложение ведет себя под нагрузкой, например, при большом количестве одновременных пользователей или операций.
Цель: Оценка производительности и устойчивости приложения под нагрузкой.
Инструменты: JMeter, Gatling, Apache Bench.
Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Что такое перегрузка метода?
Это возможность объявлять методы с одинаковым именем, но с разными параметрами (типами, количеством или порядком).
• Она позволяет создавать более гибкий и удобный интерфейс класса.
• Пример:
void Print(string message) { ... }
void Print(int number) { ... }
Каждый из методов будет вызываться в зависимости от переданных аргументов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
• Она позволяет создавать более гибкий и удобный интерфейс класса.
• Пример:
void Print(string message) { ... }
void Print(int number) { ... }
Каждый из методов будет вызываться в зависимости от переданных аргументов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3
🤔 В чём преимущество блока using?
Блок
🚩Основные преимущества блока
🟠Автоматическое освобождение ресурсов
Блок
🟠Сокращение количества кода
Использование блока
🟠Повышенная надежность
Блок
🟠Чистый и понятный код
Код, использующий блок
🚩Пример использования блока `using`
Работа с файлами
Ставь 👍 и забирай 📚 Базу знаний
Блок
using используется для управления временем жизни объектов, которые потребляют неуправляемые ресурсы, такие как файлы, соединения с базой данных или сетевые соединения. Основное преимущество использования блока using заключается в автоматическом освобождении этих ресурсов, что помогает предотвратить утечки ресурсов и улучшить управление памятью.🚩Основные преимущества блока
🟠Автоматическое освобождение ресурсов
Блок
using гарантирует, что метод Dispose() будет вызван автоматически, когда выполнение кода выйдет из блока using, даже если возникнет исключение. Это освобождает программиста от необходимости вручную вызывать Dispose() и уменьшает вероятность ошибок. using (StreamReader reader = new StreamReader("file.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using. 🟠Сокращение количества кода
Использование блока
using уменьшает количество необходимого кода для обеспечения правильного освобождения ресурсов. using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
// Работа с базой данных
}
// SqlConnection автоматически закрывается и освобождает ресурсы после выхода из блока using.
🟠Повышенная надежность
Блок
using повышает надежность кода, так как гарантирует, что ресурсы будут освобождены даже в случае возникновения исключений. try
{
using (StreamWriter writer = new StreamWriter("file.txt"))
{
writer.WriteLine("Hello, World!");
}
}
catch (Exception ex)
{
Console.WriteLine($"Произошла ошибка: {ex.Message}");
}
// StreamWriter автоматически закрывается и освобождает ресурсы после выхода из блока using, даже если произошла ошибка.
🟠Чистый и понятный код
Код, использующий блок
using, выглядит более чистым и упрощает понимание и сопровождение. using (MemoryStream memoryStream = new MemoryStream())
{
// Работа с MemoryStream
}
// MemoryStream автоматически освобождается после выхода из блока using.
🚩Пример использования блока `using`
Работа с файлами
using System;
using System.IO;
class Program
{
static void Main()
{
using (StreamReader reader = new StreamReader("example.txt"))
{
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
// StreamReader автоматически закрывается и освобождает ресурсы после выхода из блока using.
}
}
Ставь 👍 и забирай 📚 Базу знаний
🤔1
🤔 Может ли в абстрактном классе не быть ни одного абстрактного метода?
Да, может.
Абстрактный класс не обязан содержать абстрактные методы.
Он может использоваться как нельзя инстанцируемая базовая структура с частичной или полной реализацией, предназначенной для наследования.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Да, может.
Абстрактный класс не обязан содержать абстрактные методы.
Он может использоваться как нельзя инстанцируемая базовая структура с частичной или полной реализацией, предназначенной для наследования.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1
🤔 Что такое builder паттерн?
Это порождающий паттерн проектирования, который используется для пошагового создания сложных объектов. Он разделяет процесс конструирования объекта от его представления, позволяя создавать различные представления объекта, следуя одному и тому же процессу конструирования.
🚩Основные цели и задачи паттерна
🟠Разделение создания и представления
Отделяет процесс конструирования объекта от его представления, чтобы один и тот же процесс мог использоваться для создания различных представлений объекта.
🟠Пошаговое создание объектов
Позволяет создавать объекты поэтапно, контролируя процесс конструирования и предотвращая создание объекта в неконсистентном состоянии.
🟠Поддержка неизменяемых объектов
Может использоваться для создания неизменяемых объектов с большим количеством опций и параметров.
🚩Структура паттерна
🟠Builder
Определяет интерфейс для пошагового конструирования объекта.
🟠ConcreteBuilder
Реализует интерфейс Builder и создает конкретный продукт.
🟠Director
Управляет объектом Builder и задает алгоритм создания объекта.
🟠Product
Класс, представляющий создаваемый сложный объект.
🚩Пример использования паттерна Строитель
1⃣Определение продукта
2⃣Определение интерфейса Builder
3⃣Реализация конкретного Builder
4⃣Определение Director
5⃣Использование паттерна Строитель
🚩Плюсы
➕Контроль процесса создания
Позволяет контролировать процесс создания сложных объектов поэтапно.
➕Гибкость
Разделение конструирования и представления позволяет использовать один и тот же процесс для создания различных объектов.
➕Читаемость кода
Код становится более читаемым и поддерживаемым, так как процесс создания объекта инкапсулирован в отдельный класс.
➕Поддержка сложных объектов
Упрощает создание объектов с множеством параметров и сложной иерархией.
Ставь 👍 и забирай 📚 Базу знаний
Это порождающий паттерн проектирования, который используется для пошагового создания сложных объектов. Он разделяет процесс конструирования объекта от его представления, позволяя создавать различные представления объекта, следуя одному и тому же процессу конструирования.
🚩Основные цели и задачи паттерна
🟠Разделение создания и представления
Отделяет процесс конструирования объекта от его представления, чтобы один и тот же процесс мог использоваться для создания различных представлений объекта.
🟠Пошаговое создание объектов
Позволяет создавать объекты поэтапно, контролируя процесс конструирования и предотвращая создание объекта в неконсистентном состоянии.
🟠Поддержка неизменяемых объектов
Может использоваться для создания неизменяемых объектов с большим количеством опций и параметров.
🚩Структура паттерна
🟠Builder
Определяет интерфейс для пошагового конструирования объекта.
🟠ConcreteBuilder
Реализует интерфейс Builder и создает конкретный продукт.
🟠Director
Управляет объектом Builder и задает алгоритм создания объекта.
🟠Product
Класс, представляющий создаваемый сложный объект.
🚩Пример использования паттерна Строитель
1⃣Определение продукта
public class House
{
public string Walls { get; set; }
public string Roof { get; set; }
public string Foundation { get; set; }
public override string ToString()
{
return $"House with {Walls}, {Roof} and {Foundation}";
}
}
2⃣Определение интерфейса Builder
public interface IHouseBuilder
{
void BuildFoundation();
void BuildWalls();
void BuildRoof();
House GetHouse();
}
3⃣Реализация конкретного Builder
public class ConcreteHouseBuilder : IHouseBuilder
{
private House _house = new House();
public void BuildFoundation()
{
_house.Foundation = "Concrete Foundation";
}
public void BuildWalls()
{
_house.Walls = "Concrete Walls";
}
public void BuildRoof()
{
_house.Roof = "Concrete Roof";
}
public House GetHouse()
{
return _house;
}
}
4⃣Определение Director
public class ConstructionDirector
{
private readonly IHouseBuilder _builder;
public ConstructionDirector(IHouseBuilder builder)
{
_builder = builder;
}
public void ConstructHouse()
{
_builder.BuildFoundation();
_builder.BuildWalls();
_builder.BuildRoof();
}
}
5⃣Использование паттерна Строитель
public class Program
{
public static void Main()
{
IHouseBuilder builder = new ConcreteHouseBuilder();
ConstructionDirector director = new ConstructionDirector(builder);
director.ConstructHouse();
House house = builder.GetHouse();
Console.WriteLine(house); // Output: House with Concrete Walls, Concrete Roof and Concrete Foundation
}
}
🚩Плюсы
➕Контроль процесса создания
Позволяет контролировать процесс создания сложных объектов поэтапно.
➕Гибкость
Разделение конструирования и представления позволяет использовать один и тот же процесс для создания различных объектов.
➕Читаемость кода
Код становится более читаемым и поддерживаемым, так как процесс создания объекта инкапсулирован в отдельный класс.
➕Поддержка сложных объектов
Упрощает создание объектов с множеством параметров и сложной иерархией.
Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Как называется механизм, при котором переиспользуются одинаковые литералы?
Этот механизм называется интернирование строк (String Interning). Он позволяет хранить одинаковые строковые значения в едином пуле для экономии памяти.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Этот механизм называется интернирование строк (String Interning). Он позволяет хранить одинаковые строковые значения в едином пуле для экономии памяти.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥1
🤔 В чем отличие dispose и finalize?
Dispose и Finalize являются двумя механизмами для управления ресурсами, особенно теми, которые не управляются средой выполнения .NET, такими как файловые дескрипторы или соединения с базой данных. Они играют важную роль в освобождении ресурсов, но работают по-разному.
🚩Finalize
Можно переопределить в классе для выполнения очистки ресурсов перед тем, как объект будет собран сборщиком мусора. Этот метод вызывается сборщиком мусора автоматически, если объект уничтожается и не имеет других живых ссылок.
🚩Dispose
Является частью интерфейса
Ставь 👍 и забирай 📚 Базу знаний
Dispose и Finalize являются двумя механизмами для управления ресурсами, особенно теми, которые не управляются средой выполнения .NET, такими как файловые дескрипторы или соединения с базой данных. Они играют важную роль в освобождении ресурсов, но работают по-разному.
🚩Finalize
Можно переопределить в классе для выполнения очистки ресурсов перед тем, как объект будет собран сборщиком мусора. Этот метод вызывается сборщиком мусора автоматически, если объект уничтожается и не имеет других живых ссылок.
🚩Dispose
Является частью интерфейса
IDisposable и предоставляет явный способ освобождения управляемых и неуправляемых ресурсов. Разработчики могут вызывать Dispose вручную или использовать конструкцию using, которая гарантирует вызов Dispose по завершении блока кода.public class ResourceHolder : IDisposable
{
private bool disposed = false;
~ResourceHolder() // Финализатор
{
Dispose(false);
}
public void Dispose() // Метод Dispose из IDisposable
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождение управляемых ресурсов
}
// Освобождение неуправляемых ресурсов
disposed = true;
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍2
Пожизненная PRO подписка на easyoffer по цене одного года.
Акция до 20 февраля. Покупаешь сейчас один раз – пользуешься всю жизнь без лимита, включая все будущие функции.
Запланированные новые фичи на ближайшие пол года:
1. Агрегатор вакансий
2. Улучшение резюме, чтобы проходить ATS системы
3. Генерация уникального резюме и сопроводительного письма под вакансию
Покупай на https://easyoffer.ru/
Акция до 20 февраля. Покупаешь сейчас один раз – пользуешься всю жизнь без лимита, включая все будущие функции.
Запланированные новые фичи на ближайшие пол года:
1. Агрегатор вакансий
2. Улучшение резюме, чтобы проходить ATS системы
3. Генерация уникального резюме и сопроводительного письма под вакансию
Покупай на https://easyoffer.ru/
🤔 Можно ли передать значимый тип данных по ссылке?
Да, можно. Это делается явно, чтобы изменить оригинальное значение, а не копию.
- Обычно значимые типы передаются по значению (создаётся копия).
- Чтобы изменить исходный объект, его передают по ссылке, указав это явно (например, через ref или out).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Обычно значимые типы передаются по значению (создаётся копия).
- Чтобы изменить исходный объект, его передают по ссылке, указав это явно (например, через ref или out).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1🔥1
🤔 Что такое Dispose?
Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс
🚩Неуправляемые и управляемые ресурсы
🟠Неуправляемые ресурсы
включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
🟠Управляемые ресурсы
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.
🚩Как он работает
Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда
Пример использования Dispose
Ставь 👍 и забирай 📚 Базу знаний
Dispose метод является частью паттерна управления ресурсами, известного как "Dispose Pattern". Этот метод реализуется в классах через интерфейс
IDisposable. Цель — явное освобождение неуправляемых ресурсов и, по желанию, управляемых ресурсов, прежде чем сборщик мусора освободит объект. Это важно для эффективного управления памятью и другими системными ресурсами.🚩Неуправляемые и управляемые ресурсы
🟠Неуправляемые ресурсы
включают в себя ресурсы, которые не управляются средой CLR (Common Language Runtime), например, файловые дескрипторы, сетевые соединения или указатели на память, выделенную вне .NET среды.
🟠Управляемые ресурсы
это объекты .NET, которые занимают память и потенциально удерживают ссылки на неуправляемые ресурсы.
🚩Как он работает
Должен освобождать все неуправляемые ресурсы, занимаемые объектом, а также должен иметь возможность освобождать управляемые ресурсы, если это необходимо. Как правило, управляемые ресурсы освобождаются сами сборщиком мусора, но если управляемый ресурс включает в себя неуправляемые ресурсы, тогда
Dispose может быть вызван для их явного освобождения.public class ResourceHolder : IDisposable
{
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Освобождение управляемых ресурсов
}
// Освобождение неуправляемых ресурсов
disposed = true;
}
}
~ResourceHolder()
{
Dispose(false);
}
}
Пример использования Dispose
using (var resource = new ResourceHolder())
{
// Использование ресурса
}
// Метод Dispose автоматически вызывается при выходе из блока using
Ставь 👍 и забирай 📚 Базу знаний
👍1
🤔 Как работает Routing?
Это механизм сопоставления URL с соответствующими обработчиками в веб-приложении.
1. Сервер анализирует URL-запроса и перенаправляет его в нужный контроллер или обработчик.
2. Используется в веб-фреймворках (например, ASP.NET , Express.js) для обработки маршрутов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1. Сервер анализирует URL-запроса и перенаправляет его в нужный контроллер или обработчик.
2. Используется в веб-фреймворках (например,
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊4
🤔 Что такое исключения?
Исключения в программировании — это механизмы обработки ошибок и необычных ситуаций, которые возникают во время выполнения программы. В C# и других языках программирования исключения позволяют отделить код обработки ошибок от основного кода программы, что упрощает его чтение и поддержку.
🚩Основные понятия
🟠Исключение (Exception)
Событие, которое прерывает нормальный поток выполнения программы.
🟠Блок try
Содержит код, который может вызвать исключение.
🟠Блок catch
Содержит код, который выполняется, если возникает исключение. В catch блок можно передать параметр — экземпляр исключения, которое произошло.
🟠Блок finally
Содержит код, который выполняется в любом случае, независимо от того, произошло исключение или нет. Обычно используется для освобождения ресурсов.
🟠Бросание исключения (throw)
Механизм для явного вызова исключения.
🚩Пример использования
Основные блоки
Создание и бросание собственного исключения
Ставь 👍 и забирай 📚 Базу знаний
Исключения в программировании — это механизмы обработки ошибок и необычных ситуаций, которые возникают во время выполнения программы. В C# и других языках программирования исключения позволяют отделить код обработки ошибок от основного кода программы, что упрощает его чтение и поддержку.
🚩Основные понятия
🟠Исключение (Exception)
Событие, которое прерывает нормальный поток выполнения программы.
🟠Блок try
Содержит код, который может вызвать исключение.
🟠Блок catch
Содержит код, который выполняется, если возникает исключение. В catch блок можно передать параметр — экземпляр исключения, которое произошло.
🟠Блок finally
Содержит код, который выполняется в любом случае, независимо от того, произошло исключение или нет. Обычно используется для освобождения ресурсов.
🟠Бросание исключения (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("Возраст не может быть отрицательным.");
}
// Логика установки возраста
}
Ставь 👍 и забирай 📚 Базу знаний
🤔 Пример паттерна Строитель?
Например, при создании объекта типа "Отчёт":
- У объекта много параметров (заголовок, дата, содержимое, автор, таблицы).
- С помощью билдера можно поочерёдно вызывать методы SetTitle(), SetContent(), SetFooter() и получить готовый объект методом Build().
Этот подход улучшает читаемость и гибкость кода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Например, при создании объекта типа "Отчёт":
- У объекта много параметров (заголовок, дата, содержимое, автор, таблицы).
- С помощью билдера можно поочерёдно вызывать методы SetTitle(), SetContent(), SetFooter() и получить готовый объект методом Build().
Этот подход улучшает читаемость и гибкость кода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1