C# | Вопросы собесов
5.1K subscribers
34 photos
1 file
990 links
Download Telegram
Для чего нужны не реаляционые базы данных ?
Спросят с вероятностью 22%

Нереляционные базы данных, часто называемые NoSQL (Not Only SQL), представляют собой тип систем управления базами данных, который отличается от традиционных реляционных баз данных управления (РБДУ) своим подходом к организации, хранению и управлению данными. Основные причины использования нереляционных баз данных включают следующие аспекты:

1️⃣Гибкость схемы
Обычно не требуют фиксированной схемы данных, что делает их идеальными для случаев, когда данные неструктурированы или имеют различные структуры. Это позволяет разработчикам легко добавлять, удалять или модифицировать данные без необходимости менять всю структуру базы.

2️⃣Масштабируемость
NoSQL базы данных часто обеспечивают лучшую горизонтальную масштабируемость, то есть способность базы данных расширяться путём добавления большего количества серверов в пул ресурсов. Это особенно полезно для приложений, работающих с большими объёмами данных и высоким уровнем запросов, например, в больших интернет-проектах.

3️⃣Производительность
Благодаря оптимизации под конкретные типы запросов и данных, некоторые NoSQL системы могут обеспечить более высокую производительность по сравнению с реляционными базами данных, особенно когда речь идет о больших объемах данных и распределенных системах.

4️⃣Многообразие типов данных
NoSQL предлагает различные типы хранилищ, такие как документо-ориентированные, ключ-значение, колоночные магазины и графовые базы данных, каждый из которых оптимизирован для специфических типов запросов и приложений.

Примеры:

1️⃣Документо-ориентированные базы данных (например, MongoDB, CouchDB) хорошо подходят для хранения, извлечения и управления документо-ориентированной информацией как JSON или XML.
2️⃣Базы данных типа ключ-значение (например, Redis, DynamoDB) используются для хранения данных в виде словаря (ключ-значение), что идеально подходит для сессий пользователей, кэширования.
3️⃣Колоночные магазины (например, Cassandra, HBase) эффективны для аналитики больших данных, где необходимо быстро читать и записывать в огромные объёмы данных.
4️⃣Графовые базы данных (например, Neo4j, ArangoDB) оптимальны для данных, которые естественным образом представляют собой сети, например, социальные связи, сети доставки, системы рекомендаций.

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

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 466 вопроса на C# разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍6🔥1
🤔 Какой метод не существует в классе String?
Anonymous Quiz
11%
Substring
11%
Remove
71%
Delete
6%
Replace
👍4
Чем отличается метод Equal от == ?
Спросят с вероятностью 33%

Метод Equals и оператор == используются для сравнения объектов, но есть важные отличия в том, как они работают и когда их следует использовать.

Оператор ==

Обычно используется для сравнения двух объектов на равенство. По умолчанию для ссылочных типов (классов) он проверяет равенство ссылок, то есть две переменные считаются равными, если они указывают на один и тот же объект в памяти.
Переопределение: Можно переопределить для классов, чтобы изменить его поведение по умолчанию и включить сравнение по значению или какой-либо другой критерий. Это делается путем определения метода оператора для == и, обычно, для !=.

Метод Equals

Определение: Предназначен для сравнения текущего объекта с другим объектом на предмет их эквивалентности. Для типов значений (например, int, double) Equals сравнивает значения. Для ссылочных типов базовая реализация Object.Equals также проверяет равенство ссылок.
Переопределение: Может быть переопределён, чтобы обеспечить сравнение по значению или другим критериям для классов. Это часто делается для классов, где семантическое "равенство" объектов определяется не только их идентичностью в памяти.
public class Person
{
public string Name { get; set; }
public int Age { get; set; }

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

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

public override int GetHashCode()
{
return HashCode.Combine(Name, Age);
}

public static bool operator ==(Person left, Person right)
{
if (ReferenceEquals(left, right))
{
return true;
}

if (left is null || right is null)
{
return false;
}

return left.Equals(right);
}

public static bool operator !=(Person left, Person right)
{
return !(left == right);
}
}


В этом примере Equals и == переопределены так, что они сравнивают объекты Person на основе их свойств Name и Age, а не по ссылкам.

Используйте == для проверки идентичности объектов или если нужно переопределить поведение сравнения для типов, определяемых пользователем.
Используйте Equals для более формального и потенциально различного в каждом классе определения равенства.
Всегда переопределяйте GetHashCode при переопределении Equals или ==, чтобы поддерживать согласованность поведения в коллекциях, основанных на хэш-таблицах.

== — это оператор, который по умолчанию проверяет равенство ссылок для классов, но его можно переопределить. Equals — это метод, который можно переопределить для определения "равенства" в терминах значений или состояний объектов.


👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 466 вопроса на C# разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
Может ли быть несколько блоков catch ?
Спросят с вероятностью 22%

Можно использовать несколько блоков catch с одним блоком try. Это позволяет обрабатывать различные типы исключений по-разному, в зависимости от конкретной ошибки, которая произошла во время выполнения кода в блоке try.

Принцип работы

Когда в блоке try возникает исключение, среда выполнения .NET ищет первый блок catch, который может обработать это исключение на основе типа возникшего исключения. Процесс поиска начинается с первого блока catch, следующего за блоком try, и продолжается в порядке их объявления, пока не будет найден подходящий обработчик. Если подходящий обработчик не найден, исключение передается дальше по стеку вызовов.
try
{
// Здесь код, который может генерировать исключения
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[3]); // Это вызовет IndexOutOfRangeException
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("Индекс выходит за границы массива!");
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Попытка деления на ноль!");
}
catch (Exception ex)
{
Console.WriteLine($"Неизвестная ошибка: {ex.Message}");
}


Рекомендации по использованию

1️⃣Специфичность: Помещайте более специфичные обработчики исключений (например, IndexOutOfRangeException) перед более общими (например, Exception), чтобы обеспечить правильную обработку конкретных ошибок.

2️⃣Обработка исключений: В каждом блоке catch следует размещать код, который способен корректно обработать исключение, соответствующее этому блоку. Не злоупотребляйте общими обработчиками, так как это может замаскировать истинную природу ошибки.

3️⃣Логирование: Желательно логировать информацию об исключении, чтобы позже можно было проанализировать причины ошибок.

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

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

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 466 вопроса на C# разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍9
Есть ref out и boxing unboxing в чем их разница ?
Спросят с вероятностью 33%

ref, out, и механизмы "boxing" и "unboxing" выполняют разные задачи и используются в различных сценариях программирования. Давайте рассмотрим их подробнее, чтобы понять разницу.

ref и out

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

`ref`: Используется, когда передаваемая переменная должна быть инициализирована перед передачей в метод. Метод, получающий параметр с ref, может как читать, так и изменять значение переменной.
`out`: Похоже на ref, но не требует, чтобы переменная была инициализирована перед её передачей в метод. Метод, получающий параметр с out, обязан присвоить ему значение перед выходом из метода.
void Increment(ref int value) {
value += 1;
}

void GetValues(out int value1, out int value2) {
value1 = 10;
value2 = 20;
}

int number = 5;
Increment(ref number); // number теперь равно 6

int first, second;
GetValues(out first, out second); // first равно 10, second равно 20


Boxing и Unboxing

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

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

Пример "boxing" и "unboxing":
int val = 123;
object obj = val; // Boxing
int valAgain = (int)obj; // Unboxing


Различия

ref и out используются для передачи переменных по ссылке, позволяя методам изменять исходные значения переменных.
"Boxing" и "unboxing" касаются управления типами данных, позволяя значениям типов переходить между сферами значений и ссылок. Это влияет на производительность из-за дополнительных затрат на память и время выполнения.

ref и out применяются для управления поведением переменных при передаче в методы, в то время как "boxing" и "unboxing" связаны с преобразованием типов значений в типы ссылок и наоборот в контексте управления памятью.

👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти К списку 466 вопроса на C# разработчика. Ставь 👍 если нравится контент

🔐 База собесов | 🔐 База тестовых
👍81
В чем отличие dispose и finalize ?
Спросят с вероятностью 22%

Dispose и Finalize являются двумя механизмами для управления ресурсами, особенно теми, которые не управляются средой выполнения .NET, такими как файловые дескрипторы или соединения с базой данных. Они играют важную роль в освобождении ресурсов, но работают по-разному.

Finalize
Можно переопределить в классе для выполнения очистки ресурсов перед тем, как объект будет собран сборщиком мусора. Этот метод вызывается сборщиком мусора автоматически, если объект уничтожается и не имеет других живых ссылок.

Недостатки:
Непредсказуемость: Не определено точное время, когда сборщик мусора вызовет 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;
}
}
}


В этом примере класс ResourceHolder реализует IDisposable и имеет финализатор. Если метод Dispose() вызван явно или через using, то ресурсы освобождаются немедленно, а вызов финализатора подавляется функцией GC.SuppressFinalize(this). Если Dispose() не вызван, то очистка ресурсов произойдет, когда сборщик мусора вызовет финализатор.

Dispose предназначен для явного управления освобождением ресурсов, что позволяет контролировать время их освобождения. Finalize используется для аварийной очистки, когда ресурсы не были освобождены должным образом. Использование Dispose считается более предпочтительным с точки зрения управления ресурсами и производительности программы.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
🤔 Какой из нижеперечисленных типов данных является ссылочным в C#?
Anonymous Quiz
2%
int
3%
bool
93%
string
2%
double
В чём отличие thread от task ?
Спросят с вероятностью 33%

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

Thread

Это более традиционный способ работы с многопоточностью, который позволяет создавать и управлять потоками напрямую. Каждый поток Thread занимает определённый объем системных ресурсов, включая стек памяти, и выполняется на отдельных ядрах процессора.

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

Task

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

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

Thread
using System;
using System.Threading;

class Program
{
static void Main()
{
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
thread.Join();
}

static void DoWork()
{
Console.WriteLine("Working on a thread from Thread class.");
}
}


Task
using System;
using System.Threading.Tasks;

class Program
{
static async Task Main()
{
Task task = Task.Run(() => DoWork());
await task;
}

static void DoWork()
{
Console.WriteLine("Working on a thread from Task class.");
}
}


Использование Task является предпочтительным для большинства асинхронных операций из-за его гибкости, масштабируемости и удобства в использовании. Однако Thread может быть необходим в сценариях, где требуется более тонкое управление над потоками или когда задача требует постоянного взаимодействия с потоком.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥1
Что известно про SQL ?
Спросят с вероятностью 22%

SQL (Structured Query Language — язык структурированных запросов) — это специализированный язык программирования, используемый для управления данными в системах управления базами данных (СУБД), таких как SQL Server, Oracle, MySQL, SQLite и PostgreSQL. Этот язык позволяет выполнять различные операции с данными, включая их создание, изменение, управление и извлечение.

Основные возможности:

1️⃣DML (Data Manipulation Language) — Язык манипулирования данными:
SELECT — извлечение данных из базы данных.
INSERT — вставка новых данных в таблицы.
UPDATE — обновление существующих данных.
DELETE — удаление данных.

2️⃣DDL (Data Definition Language) — Язык определения данных:
CREATE — создание новых таблиц или баз данных.
ALTER — модификация существующей структуры таблиц или баз данных.
DROP — удаление таблиц, баз данных.

3️⃣DCL (Data Control Language) — Язык контроля данных:
GRANT — предоставление прав доступа пользователям и ролям.
REVOKE — отзыв прав доступа.

4️⃣TCL (Transaction Control Language) — Язык управления транзакциями:
COMMIT — подтверждение транзакции.
ROLLBACK — откат изменений до начала транзакции или к сохранённой точке.
-- Выборка всех данных из таблицы пользователей
SELECT * FROM Users;

-- Вставка нового пользователя
INSERT INTO Users (Username, Age) VALUES ('Ivan', 25);

-- Обновление данных пользователя
UPDATE Users SET Age = 26 WHERE Username = 'Ivan';

-- Удаление пользователя из таблицы
DELETE FROM Users WHERE Username = 'Ivan';


Почему он так важен?

SQL является стандартом в области управления реляционными базами данных. Он позволяет эффективно управлять большими объемами данных, обеспечивает безопасность данных и поддерживает сложные запросы. Это делает SQL незаменимым инструментом для разработчиков, аналитиков данных и администраторов баз данных.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
🤔 Какой метод из `System.Threading.Tasks.Task` является асинхронным?
Anonymous Quiz
9%
Start
33%
Wait
23%
ContinueWith
35%
Run
👍6🤔1
Как работает сборщик мусора ?
Спросят с вероятностью 22%

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

1️⃣Фаза маркировки

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

2️⃣Фаза очистки

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

3️⃣Фаза компактификации (не всегда)

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

Поколения объектов

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

Поколение 0: Включает новые объекты. Поскольку многие объекты умирают молодыми, поколение 0 собирается часто.
Поколение 1: Служит буферной зоной между часто собираемыми молодыми объектами и объектами с долгим временем жизни. Это поколение собирается реже.
Поколение 2: Включает объекты с долгим временем жизни. Сборка мусора в этом поколении происходит редко.

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102
Что такое IEnumerable ?
Спросят с вероятностью 22%

IEnumerable — это интерфейс в базовой библиотеке классов .NET Framework, который определяет один метод: GetEnumerator(). Этот метод возвращает объект IEnumerator, который позволяет перебирать элементы коллекции (например, массива или списка) один за другим.

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

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

Как он используется?

Когда вы реализуете интерфейс IEnumerable в своём классе, вы обязуете этот класс предоставлять метод GetEnumerator(), который возвращает IEnumerator. IEnumerator, в свою очередь, имеет методы для перехода к следующему элементу (MoveNext) и для получения текущего элемента (Current), а также метод Reset(), который возвращает перечислитель в начальное состояние.
using System;
using System.Collections;

public class DaysOfWeek : IEnumerable
{
private string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };

public IEnumerator GetEnumerator()
{
for (int index = 0; index < days.Length; index++)
{
// Yield each day of the week.
yield return days[index];
}
}
}

public class Program
{
public static void Main()
{
DaysOfWeek daysOfWeek = new DaysOfWeek();
foreach (string day in daysOfWeek)
{
Console.WriteLine(day);
}
}
}


В этом примере класс DaysOfWeek реализует IEnumerable, что позволяет использовать его в цикле foreach для вывода всех дней недели. Использование yield return в методе GetEnumerator() упрощает создание итератора.

IEnumerable позволяет объектам быть перебираемыми в цикле foreach. Это дает возможность скрыть внутреннюю реализацию коллекции, предоставляя простой и понятный интерфейс для доступа к её элементам. Также это способствует созданию кода, который легче читать и поддерживать.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥5🤔21
Зачем нужны поколения для сборщика мусора ?
Спросят с вероятностью 22%

Поколения в сборке мусора (.NET Garbage Collector) играют важную роль в оптимизации процесса управления памятью. Использование поколений основывается на наблюдении, известном как "гипотеза о слабой генерализации", которая гласит, что большинство объектов умирает молодыми. Это означает, что объекты, которые были недавно созданы, с большей вероятностью будут недоступны или "умрут" быстро, в то время как объекты, которые уже существовали в течение более длительного времени, вероятнее всего, будут нужны программе еще дольше.

1️⃣Улучшение производительности

Сбор мусора может быть затратным с точки зрения производительности, особенно если он запускается часто или должен проверять большое количество объектов. Разделение объектов на поколения позволяет сборщику мусора оптимизировать свою работу:

Частые сборы в младших поколениях: Поскольку большинство объектов умирает молодыми, частая сборка мусора в поколении 0 (где находятся новые объекты) быстро освобождает память, занимаемую недолговечными объектами, с минимальными затратами времени.
Реже сборы в старших поколениях: Объекты, которые выжили несколько сборок мусора и были продвинуты в поколение 1 и далее в поколение 2, проверяются на достижимость менее часто, что снижает нагрузку на систему.

2️⃣Минимизация фрагментации памяти

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

3️⃣Сокращение времени простоя

Интеллектуальное управление поколениями позволяет сборщику мусора выполнять полную сборку мусора (включающую все поколения) гораздо реже, что сокращает время простоя приложения, связанное с сбором мусора. Таким образом, приложения работают более плавно и с меньшими задержками.

В приложении, где создаются множество временных объектов (например, в результате парсинга данных или обработки запросов пользователя), сборщик мусора быстро удаляет эти объекты в поколении 0, предотвращая накопление "мусора" и сохраняя высокую производительность приложения.

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
Forwarded from easyoffer
Канал приближается к 20к подписчиков, а здесь так и нет нормального контент плана 😒

Ищу талантливых журналистов, способных писать клевые и авторские посты на тему "Карьера в IT" и все что с этим связано: поиск работы, повышение з/п, разбор кейсов, переезд в другие страны по рабочим визам, аналитика, исследование рынка и т.д.

Важно глубокое понимание IT индустрии, вы должны иметь опыт работы в ней

Если интересно отправьте мне свое резюме @kivaiko
👍3🔥2
🤔 Какой модификатор доступа делает класс доступным только в текущей сборке?
Anonymous Quiz
2%
public
8%
private
78%
internal
11%
protected
👍21
Какие проблемы могут быть при многопоточности и как их избежать ?
Спросят с вероятностью 22%

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

Основные проблемы:

1️⃣Гонки данных (Race Conditions)
Проблема: Два или более потоков пытаются одновременно изменить общие данные или один поток читает данные во время их изменения другим потоком, что приводит к непредсказуемым результатам.
Решение: Использование механизмов синхронизации, таких как блокировки (locks), мьютексы (mutexes) и семафоры (semaphores), для контроля доступа к общим ресурсам.

2️⃣Взаимная блокировка (Deadlock)
Проблема: Два или более потоков бесконечно ожидают ресурсы, заблокированные друг другом, в результате чего они не могут продолжить выполнение.
Решение: Разработка программы таким образом, чтобы потоки запрашивали ресурсы всегда в одном и том же порядке, использование таймаутов для блокировок, чтобы потоки могли выйти из состояния ожидания.

3️⃣Голодание (Starvation)
Проблема: Один или несколько потоков не могут получить доступ к необходимым ресурсам, потому что другие потоки постоянно занимают их.
Решение: Применение справедливых блокировок (fair locks) или алгоритмов планирования, которые обеспечивают всем потокам равный доступ к ресурсам.

4️⃣Переключение контекста (Context Switching)
Проблема: Частое переключение контекста между потоками может значительно снизить производительность системы, особенно если потоки часто блокируются и разблокируются.
Решение: Оптимизация количества потоков, уменьшение зависимостей между потоками и уменьшение использования блокировок.

5️⃣Проблемы с проектированием
Проблема: Неправильное проектирование многопоточной архитектуры может привести к сложностям в поддержке и расширении программного обеспечения.
Решение: Использование абстракций высокого уровня для работы с потоками, таких как пулы потоков, параллельные библиотеки (например, TPL в .NET) и модели акторов.

Использование блокировки:
private static readonly object _lock = new object();
private static int _sharedResource;

public static void UpdateResource()
{
lock (_lock)
{
_sharedResource++;
// Выполнение некоторой работы с общим ресурсом
}
}


Этот пример показывает использование объекта блокировки для предотвращения гонки данных при доступе к общему ресурсу.

Избегание взаимной блокировки:
private static readonly object _lock1

= new object();
private static readonly object _lock2 = new object();

public static void Method1()
{
lock (_lock1)
{
// Некоторые действия
lock (_lock2)
{
// Дополнительные действия
}
}
}

public static void Method2()
{
lock (_lock1)
{
// Аналогичные действия
lock (_lock2)
{
// Дополнительные действия
}
}
}


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

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥31
Какие API можно назвасть Restо-вым ?
Спросят с вероятностью 22%

RESTful API (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов в сети. Создание его включает в себя следование ряду принципов, которые делают API легко использовать и интегрировать в различные приложения. Основные принципы REST включают использование стандартных методов HTTP, семантически ясных URL и передачу данных в форматах, таких как JSON или XML. Чтобы API можно было назвать RESTful, он должен следовать этим ключевым принципам:

1️⃣Использование стандартных методов HTTP:
GET: Получение данных.
POST: Создание новой записи.
PUT: Обновление существующей записи.
DELETE: Удаление записи.

2️⃣Без сохранения состояния (Stateless):
Каждый запрос от клиента к серверу должен содержать всю информацию, необходимую для выполнения запроса. Сервер не должен хранить контекст клиента между запросами.

3️⃣Кэширование:
Ответы должны быть явно маркированы как кэшируемые или некэшируемые, чтобы клиенты могли избежать повторной отправки запросов за неизменной информацией.

4️⃣Единообразие интерфейса:
Интерфейс должен быть единообразным, что облегчает взаимодействие с API. URL должны быть структурированы логически, а передача данных должна быть прозрачной и понятной.

5️⃣Слоистая система:
Клиент не должен обязательно знать, общается ли он напрямую с сервером или через промежуточные слои (прокси, балансировщики нагрузки).

Примеры популярных RESTful API:

GitHub API: Предоставляет доступ к функциям, таким как репозитории, коммиты, вопросы и т.д., используя стандартные методы HTTP для управления ресурсами.

Twitter API: Позволяет разработчикам взаимодействовать с основными аспектами Twitter, включая твиты, профили пользователей и т.д.

Google Maps API: Дает возможность добавлять карты Google и другие функции местоположения в веб-сайты и приложения.

Amazon S3 API: Обеспечивает программный доступ к функциям хранения файлов на Amazon S3.

Эти API являются примерами, как можно организовать взаимодействие между клиентом и сервером, используя принципы REST для обеспечения гибкости, масштабируемости и удобства интеграции.

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
В чем разница между процессами и потоками ?
Спросят с вероятностью 22%

"процесс" и "поток" относятся к фундаментальным аспектам управления выполнением задач в операционных системах. Хотя оба являются единицами выполнения, они имеют существенные различия и используются в разных контекстах.

Процесс

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

Изоляция: Процессы изолированы друг от друга, что обеспечивает безопасность и стабильность системы. Ошибка в одном процессе обычно не влияет на работу других процессов.
Переключение контекста: При переключении между процессами операционная система должна сохранять и восстанавливать контекст процесса, что может быть ресурсоёмкой операцией.
Взаимодействие: Процессы могут взаимодействовать друг с другом через механизмы межпроцессного взаимодействия (IPC), такие как сокеты, файлы, общая память и другие.

Поток (Thread)

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

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

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

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82
Что такое ref & out ?
Спросят с вероятностью 22%

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

ref

Используется для передачи переменной по ссылке. Это означает, что любые изменения, сделанные с переменной внутри метода, отражаются на исходной переменной, переданной из вызывающего кода. Важно отметить, что переменная, передаваемая с модификатором ref, должна быть инициализирована перед передачей в метод.
void Increment(ref int number)
{
number += 1;
}

int value = 5;
Increment(ref value);
Console.WriteLine(value); // Выведет 6


В этом примере value передаётся по ссылке, так что изменения в методе Increment видны и снаружи метода.

out

Также используется для передачи аргументов по ссылке, но оно имеет одно ключевое отличие от ref: переменная, передаваемая с out, не обязательно должна быть инициализирована до её использования в методе. Однако метод, получающий параметр out, обязан присвоить этой переменной значение до выхода из метода.
void GetCoordinates(out int x, out int y)
{
x = 10;
y = 20;
}

int a, b;
GetCoordinates(out a, out b);
Console.WriteLine(a); // Выведет 10
Console.WriteLine(b); // Выведет 20


Здесь переменные a и b не были инициализированы перед передачей в метод GetCoordinates. Метод же устанавливает их значения, которые затем доступны после выполнения метода.

Сравнение ref и out

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

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

🔥 ТОП ВОПРОСОВ С СОБЕСОВ

🔒 База собесов | 🔒 База тестовых
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31