Skip to content

Latest commit

 

History

History
114 lines (86 loc) · 6.41 KB

0001.как я на собеседование ходил.md

File metadata and controls

114 lines (86 loc) · 6.41 KB

Ходил на собеседование 23 марта 2021.

Дали задачку

Выполните письменное задание. Можно гуглить, ориентир по времени – 25 минут

Есть класс

class TreeNode
{
    public IEnumerable<TreeNode> Children { get; }
}

Напишите функцию

IEnumerable<TreeNode> GetAllNodes(TreeNode node) {
    // тут надо написать код
}

Эта функция должна возвращать IEnumerable<TreeNode>, содержащий все элементы переданного в неё дерева, всех уровней вложенности.

Спрашиваю про порядок обхода, получаю ответ «на ваше усмотрение».

За отведённое время успеваю наколбасить решение, попутно размышляя о том, что Aux – ужасное имя, что «тестик» в Main – это убого и не позволит ничего поправить на ходу, так как не будет гарантии, что ничего не сломается – всё то, за что в своё время на собеседованиях мы журили испытуемых.

Ещё проскакивает мысль, что List повсюду плохо согласуется с IEnumerable и по красоте надо с yield сделать, но понимаю, что за 25 минут не успею.

Показываю решение, меня спрашивают, что в нём не очень. Я мямлю что-то невразумительное про разрастание стека и рекурсивные вызовы.

Просят написать тест для дерева из примера. Пишу

    var root = new TreeNode();
    var childA = new TreeNode();
    var childB = new TreeNode();
    root.Children = new List<TreeNode>() { childA, childB };
    var actual = GetAllNodes(root);
    actual.ToList() == new List<TreeNode>() { root, childB, childA };

сопровождая ремаркой о том, что тут должен быть assert

Мне говорят, что такой ассёрт будет проваливаться. Я невнятно говорю, что из-за сравнения массивов, и надо использовать какой-нибудь метод, который я на память не помню, но должен же быть в nUnit подобный. Или на худой конец в FluentAssertion.

На этом разговор про эту задачу заканчивается.

Далее «домашняя работа», она же «работа над ошибками».

Первым делом добавляю тестов:

mkdir ListAllNodesTests
cd ListAllNodesTests 
dotnet new xunit
dotnet add reference  ../ListAllNodes/ListAllNodes.csproj
cd ..
dotnet sln add ./ListAllNodesTests/ListAllNodesTests.csproj

и сам тест. И он проходит...

То ли меня хотели сбить с толку (и это удалось), то ли собеседующий сам что-то подзабыл/напутал.

Пробую nUnit:

mkdir ListAllNodesNunitTests
cd ListAllNodesNunitTests
dotnet new -i NUnit3.DotNetNew.Template
echo ../ListAllNodes/ListAllNodes.csproj | xargs dotnet add reference
cd ..
echo ./ListAllNodesNunitTests/ListAllNodesNunitTests.csproj| xargs dotnet sln add

dotnet new -i NUnit3.DotNetNew.Template взято из документации

Возня с xargs вызвана тем, что у меня не получается нормально автокомплит для add reference – не хочет подсказывать пути к файлам проекта (upd 2022-02-23: dotnet/sdk#9782)

nUnit также благополучно проходит, пробую задаунгрейдить версию до 2.7, снова получают успешное прохождение.

Немного размышляю и меня осеняет, что это в буквальном смысле одни и те же объекты – GetAllNodes возвращает список тех же ссылок на те же объекты. Гуглю DeepCloner, добавляю result.Add(last.DeepClone()), и тест начинает падать.

Добавляю FluentAssertions и

treeNodes.Should().BeEquivalentTo(new[] {root, childA, childB}, options => options.WithStrictOrdering());

Тест зелёный. Меняю местами childA и childB – снова зелёный... Ну, конечно же, – два листа не отличаются друг от друга!

День третий.

Цепляю библиотеку BenchmarkDotNet с [MemoryDiagnoser]

Первый прогон показывает

BenchmarkDotNet=v0.12.0, OS=macOS 11.2.3 (20D91) [Darwin 20.3.0]
Intel Core i5-8259U CPU 2.30GHz (Coffee Lake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.103
  [Host]     : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
  DefaultJob : .NET Core 3.1.1 (CoreCLR 4.700.19.60701, CoreFX 4.700.19.60801), X64 RyuJIT
Method Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
StackyRecursiveBenchmark 201.3 ns 4.24 ns 8.65 ns 0.1044 - - 328 B

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