Вопрос – Ответ
January 14, 2019

Вопросы на собеседованиях по C# и .Net. На позицию junior/middle. Часть 2.


!!НАШ БЛОГ ПЕРЕЕХАЛ!!

Мы создали свой сайт! Все материалы, опубликованные в этом блоге, переехали туда.

Наш новый сайт maddevelop.ru

А данную статью вы можете найти по ссылке ниже:

https://maddevelop.ru/Textbook/ViewSelectedArticle?textbookName=C%23&sectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BF%D0%BE%20C%23%20%D0%B8%20.NET&subsectionName=%D0%A1%D0%BE%D0%B1%D0%B5%D1%81%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BD%D0%B0%20%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D1%8E%20junior%2Fmiddle&articleName=%232%20%D0%91%D0%BB%D0%BE%D0%BA%20%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2%20(%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B%206-10)

P.S. движок teletype.in очень странно интерпретирует ссылку, и пришлось вставлять ее полным текстом


Вопрос 6

Какие результаты выведет следующий код:

internal class Program
{
    private static Object syncObject = new Object();
    private static void Write()
    {
        lock (syncObject)
        {
            Console.WriteLine("test");
        }
    }
    static void Main(string[] args)
    {
        lock (syncObject)
        {
            Write();
        }
    }
}

Варианты ответов:

  1. Выбросит исключение
  2. Напечатает слово "test"
  3. Произойдет взаимоблокировка (deadlock)
  4. Напечатает слово "test" бесконечное число раз

Ответ:

Правильный ответ под номером 2 ("Напечатает слово test"). В этом коде нет никаких причин для появления исключений. Взаимоблокировка тоже не возникает, потому что вся программа выполняется в одном потоке.

Вопрос 7

Даны следующие классы:

public class A
{
    public virtual void Print1()
    {
        Console.Write("A");
    }
    public void Print2()
    {
        Console.Write("A");
    }
}
public class B: A
{
    public override void Print1()
    {
        Console.Write("B");
    }
}
public class C : B
{
    new public void Print2()
    {
        Console.Write("C");
    }
}

К какому результату приведет выполнение следующего кода:

var c = new C();
A a = c;
 
a.Print2();
a.Print1();
c.Print2();

Варианты ответов:

  1. ABC
  2. CCC
  3. ACC
  4. AAC

Ответ:

Верный ответ под номером 1 (ABC).

Вызов a.Print2() возвращает A, потому что в переменной a содержится ссылка на объект класса C. Этот класс наследуется от класса B (наследника класса А) и в своем теле перекрывает с помощью оператора new метод, содержащийся в классе A. В этом случае полиморфизм не будет работать и когда будет вызван метод a.Print2() выполнится код из базового класса А.

Вызов a.Print1() возвратит B, потому что класс C наследуется от B, а в нем, в свою очередь переопределен метод Print1() следовательно и вызываться он будет из класса B.

Вызов c.Print2() возвратит С. Ну здесь все просто, вызывается метод объекта класса C.

Вопрос 8

Что будет выведено на консоль в результате выполнения следующего кода:

static IEnumerable<int> Square(IEnumerable<int> a)
{
    foreach(var r in a)
    {
        Console.WriteLine(r * r);
        yield return r * r;
    }
}
class Wrap
{
    private static int init = 0;
    public int Value
    {
        get { return ++init; }
    }
}
static void Main(string[] args)
{
    var w = new Wrap();
    var wraps = new Wrap[3];
    for(int i=0; i<wraps.Length; i++)
    {
        wraps[i] = w;
    }
 
    var values = wraps.Select(x => x.Value);
    var results = Square(values);
    int sum = 0;
    int count = 0;
    foreach(var r in results)
    {
        count++;
        sum += r;
    }
    Console.WriteLine("Count {0}", count);
    Console.WriteLine("Sum {0}", sum);
 
    Console.WriteLine("Count {0}", results.Count());
    Console.WriteLine("Sum {0}", results.Sum());
}

Ответ:

На консоль выведется:

1
4
9
Count 3
Sum 14
16
25
36
Count 3
49
64
81
Sum 194

Принцип состоит в том, что мы сначала создаем массив элементов Wrap и заполняем его элементами w. Массив в итоге будет таким [1, 2, 3]. Далее создается linq запрос var values = wraps.Select(x=>x.Value), который будет выполняться при каждом новом обращении к values, тем самым пересоздавая массив заново. Этот запрос вызывается и когда мы проходим циклом foreach по массиву results, и когда вызываем метод Count() над results, и когда вызываем метод Sum().

Вопрос 9

Является ли тип List потокобезопасной (thread-safe) коллекцией?

Варианты ответов:

  1. Только при операциях чтения
  2. Не является ни в каком случае
  3. Только при операциях записи
  4. Является во всех случаях

Ответ:

Если руководствоваться MSDN тип List может быть потокобезопасным в операциях чтения (Ответ 1)

Если выполняется только чтение из общей коллекции, вы можете использовать классы в пространстве имен System.Collections.Generic.
Классы коллекций, представленные в .NET Framework 2.0, находятся в пространстве имен System.Collections.Generic. К ним относятся List<T>Dictionary<TKey,TValue> и др. Эти классы отличаются улучшенной безопасностью типа и производительностью по сравнению с классами .NET Framework 1.0.Однако классы коллекций .NET Framework 2.0 не обеспечивают синхронизацию потоков. Пользовательский код должен обеспечивать всю синхронизацию при параллельном добавлении элементов в несколько потоков или удалении элементов из них.

Ссылка на статью

Вопрос 10

В чем различие между операцией cast (приведения типов) и оператором as?

  1. Оператор "as" - это просто синтаксический сахар для "cast"
  2. Cast изменяет динамический тип, в то время как as изменяет статический тип
  3. В случае ошибки cast выбрасывает исключение InvalidCastException, а оператор as возвращает null
  4. В случае ошибки cast возвращает null, а оператор as выбрасывает исключение InvalidCastException

Ответ:

Правильный ответ 3.

На эту тему можно прочитать:

Что такое оператор as

Приведение типов

и еще одна интересная статья



Ещё больше интересной информации на нашем Telegram канале.

<< К части 1 << ......... >> К части 3 >>

Источники вопросов:

Metanit. Собеседование по C#. Часть 2

Metanit. Собеседование по C#. Часть 3