Как стать автором
Обновить

Комментарии 120

А разве в c# есть final?
Есть. Только он называется sealed.
Это вопрос с подвохом. Позволяет проверить путает ли кандидат C# и Java.
Т.е. ответ «не знаю что делает кейворд final» — будет правильным? :)

По моему плохой вопрос, это же тест по C# и вопрос про несуществующий кейворд ставит в тупик.
Если бы тут не спросили про Java, не вспомнил бы что это оттуда.
>> «не знаю что делает кейворд final» — будет правильным? :)

Да. Но я встречал ответы и по-лучше, например «Я точно не помню, но легко найду в гугле».
:)) Да, тут есть хорошая доля иронии :)

Кстати, еще момент. По поводу вопросов где нужно описать подробнее — неплохо бы об этом упоминать. Типа: «Возможно ли сделать так-то-так-то? Почему?». Будет больше адекватных ответов.
Для этого есть устное собеседование.
Ну, тогда ок :)
Никогда в жизни не видел С#, но штук на 10 вопросов ответил точно. Странные программисты, пришедшие на эту должность, и ответившие только на 12 вопросов =\
А опрос хороший, всегда бы такие устраивали, может было бы меньше дилетантов.
НЛО прилетело и опубликовало эту надпись здесь
Да, правда, дочитал до конца. Я не си-шарпник, так что не смог сразу оценить. Спасибо :)
Это точно вопросник по шарпу?

Этот вопросник рассчитан на человека, который прочитал книжку «Язык C# и основы .NET», а не на разработчика, и годится только для того, чтобы при приеме на работу взять студента, который хоть немного в теме, вместо того, который не в теме вообще.
Ну в заголовке же написано Developer, а не Senior Developer ;-) Кроме того далеко не все вопросы так просты как кажутся.
По-моему, даже для developer гораздо важнее тредпул, асинхронные операции, интероп и датасет, чем вопрос на тему, может ли выйти break из блока finally. Я, честно говоря, сам не знаю, потому что никогда в жизни break-ом из finally не выходил, хотя скорее всего не может.

Кроме того, в шарпе нормальный программер пользуется инструкцией sizeof ровно ноль раз в жизни, потому что unsafe контекст — это зло для тех, кто не знает с++ и не может написать критичный по скорости блок на нем. Либо для каких-то очень спецефических применений.
Я бы не стал человека с 1-2 годом работы подпускать к интеропу, учитывая что в моих проектах он должен быть расчитан на ARM/x86/x64, и многопоточности, учитывая что это многопоточность.
Интероп требует как раз того самого, на что рассчитан вопросник — кропотливого зубрения принципов и характерных конфигураций для различных типов маршаллинга. При наличии всего этого за него можно сажать обезьяну.

Про аппдомен бы еще спросили, это ж самая база. Про которую, правда, почему-то никто не помнит.
AppDomain редко используется на практике, в Моно их АФАИК вообще нет.
У AppDomian-а есть одно незаменимое применение — изоляция сборок.

В случае, если ваше приложение планирует работать с плагинами — самое оно. Ну или просто, если у разных частей приложения должны быть разные уровни доверия.
Ну и как часто это бывает надо?
Мне понадобилось как минимум один раз в жизни.
А мне раз 5. Знать это разработчику с 1-2 годом опыта ИМХО не обязательно.
У меня опыт работы с C# чуть более полутора лет.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Все ValueType инстанцируются в стеке, здрасьте приехали.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Может быть, что-то есть в Marshall, но я не знаю — никогда не занимался инстанцированием объектов в стеке вручную.

А вам зачем? Может, можно сделать то же самое малой кровью?
НЛО прилетело и опубликовало эту надпись здесь
GC автоматически при сборке мусора дефрагментирует память, так что нет нужды заботиться об этом.

Я вам посоветую не заниматься оптимизацией того, что оптимизировать не нужно. Это в C++ были нужны smart pointers, не надо пытаться сделать их на C#, у него совершенно другая парадигма. Я еще не видел ни одного приложения, в котором сборка мусора была бы критична для производительности, а те, что подходили к этому пределу — были настолько криво спроектированы (как вам аллоцирование в цикле 100 метров памяти?), что хотелось плакать.
НЛО прилетело и опубликовало эту надпись здесь
Я думаю, что как раз в этом случае лучше все-таки использовать более низкоуровневые языки.
НЛО прилетело и опубликовало эту надпись здесь
Ну ObjC гораздо больше C++, чем С#, в котором от первого остался только синтаксис.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
То есть в Marshal. Marshall — это комбик такой, для гитары.
Несколько комментариев.

2. What is a 'static' class?

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

7. How 'System.String' class differs from most of other classes?

Порясающий ответ «It is defined in mscorlib.dll» формально верен, но вообще-то надо что-то сказать на тему immutable.

11. What does keyword 'mutable'?

Проверяет на путаницу с Си++

13. What does operator 'as' do?

Надо рассказать про отсутсвие исключения в случае неудачи. Простое casts to a type не годится.

14. What does keyword 'final'?

Проверяет на путаницу с Java.

17. What is event?
18. What is the difference between event and delegate?

На эти два вопроса никто не ответил правильно. Удивительно, что они такие сложные.

19. Are events synchronous or asynchronous?

Некоторые писали что события асинхронны, а потом оправдывались что говорили про оконные сообщения.

20. What does keyword 'safe'?

Нет такого слова в этой букве :-)

24. What is special about the declaration of relational operators?
25. How 'public internal' access modifier affects visibility?

Почти никто не ответил правильно.

26. Can a local variable get garbage collected before it becomes out-of-scope?

Как бы проверка вопроса №6

27. What implementations of serialization are built in FCL? Where are they used?

Хорошо бы рассказать про AppDomain'ы и неявную сереализацию при передаче объекта, например исключения, в другой домен.

30. How to apply attribute to method return value?
32. What is purpose of 'IDisposable' interface?

Вопрос вроде бы про язык, но на самом деле это проверка много ли работал человек с Интеропом.

31. What is the difference between C# class finalizer and C# class destructor?

К качестве ответа на этот вопрос было написано много феерического бреда.

33. Can an array be resized at runtime?

И да, и нет. Да, есть Array.Resize, нет — внутри он занимается копированием.

36. What is smallest integer type to represent number not greater than 40 000?

ushort — ответ на троечку. Хороший ответ — long.

41. What encoding uses 'System.String' class?

99% ответов — UTF8. Печально.

46. Does C# have “friendship”?

Надо рассказать про InternalsVisibleToAttribute

47. What is the 'using' statement for?

Два назначения, описать оба.

48. Can a struct have methods?

Часто отвечают — нет.

49. Can a struct be inherited?

Часто отвечают — да.

50. Why do most event handlers use signature 'void(object, EventArgsDerivative)'?

Надо написать про приведение типов.
Забавно, никогда не знал, что .NET позволяет менять видимость атрибутами.

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

И, в C# разве есть деструкторы. Насколько я знаю, ~ClassName() — это не деструктор.
31. What is the difference between C# class finalizer and C# class destructor?

no difference.

~ClassName() это декструктор в терминологии C# и финалайзер в терминологии .Net Framework.
Начиная с 3-й версии C# неразбериху в терминологии документации ликвидировали.

Впрочем феерического бреда про разницу между деструктором и финалайзером я начитался.
Видимо, я как-то не застал эпоху неразберихи в терминах, потому что для меня всегда было так, что ~ClassName() в С++ — это деструктор, а ~ClassName() в C# — это финализатор.
на самом деле, тупой вопрос.
>36. What is smallest integer type to represent number not greater than 40 000?
> ushort — ответ на троечку. Хороший ответ — long.

Почему? Возможно наиболее правильным ответом было бы уточнение про отрицательные числа. Если они не используются, то ushort вполне подойдет, или int, если используются и есть соответствующие ограничение. А то сразу отвечать 8-байтный long ИМХО как-то неправильно…
int — человек не думал
ushort — подумал
long — ещё подумал
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
26. Can a local variable get garbage collected before it becomes out-of-scope?
Для reference type ответ, да.
предлагаю догадаться как любой объект имея reference на себя может быть собран GC.
А что там догадываться? GC умеет разрешать циклические ссылки.

Но вопрос в том, что может ли быть переменная быть уничтожена сборщиком мусора, прежде чем выйдет из области видимости? То есть можно ли сделать delete ручками?

Нет, delete ручками сделать нельзя. Можно объявить WeakReference, но это считается выходом из области видимости.
дану, с WeakReference вы имеете ссылку на объект (_технически_ это выход за область видимости, но это «тайна» конкретной реализации).

Можно утверждать что ссылки из C# это поинтеры на память и это будет правдой в конкретной реализации рантайма, но не будет правдой в рамках концепции С#.
С WeakReference нельзя сказать, имеете ли вы ссылку на объект, потому что сегодня она есть, а завтра ее уже нет.
ссылка некуда не девается, а вот сам объект может уже рассказывать истории своей жизни в раю для объектов.

вопрос спорный, но стоит разработчикам языка ввести «сахар» в виде ключевого слова «weak» перед объявлением переменной и ответ на вопрос №26 для большинства был бы «да может».
Weak references нужны не настолько часто, чтобы для них имело смысл подобное.

Тем более, что вы всегда можете написать для себя generic class, который будет работать с weak references так, как вам надо.
моя мысль в том, что вопросы неоднозначны настолько, что судить по количеству «правильных» ответов неправильно, тут полезнее интерпретировать реакцию.

к примеру: 19. Are events synchronous or asynchronous?
первая реакция: wtf?! события не процессы, они не могут быть синхронны или асинхронны.
если вопрос о вызове событий, то там всё держится на фантазии разработчика.

шонить типа такого и добро пожаловать в мир асинхронного вызова событий:
var ivocationResults = this.MyEvent.GetInvocationList().Parallel(del => del.DynamicInvoke(null));
Для WinForms скорее всего не сработает, кстати — там STA, и доступ из других потоков для объектов формы запрещен.

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

Общее правило такое — всегда вызывать событие синхронно.
>Потому что никогда не знаешь, что по твоему событию будут делать

имеено по этой причине делают асинхронный вызов события. К примеру покемон(«разраб»-разнорабочий) решил в обработчике события обратиться к сайту bigboobs.com и 12 минут будет ждать ответа, а у тя транзакция горит :)
К примеу покемон решил в обработчике событий повесить на форму курсор с часиками. Он очень долго (я гарантирую) будет чесать репу, выясняя, почему у него в обработчике событий сменился поток и что ему теперь делать.
var doItFaggot = delegate ( Cursor cursor ) { form.Cursor = cursor; }

if ( form.InvokeRequired )
form.Invoke( doItFaggot, megaCursor );
else
doItFaggot( megaCursor );

если покемон незнает про это, то ему надо продавать шаурму в киоске, а не рисовать мышкой формы.
И этот боян мне надо писать каждый раз? Спасибо.

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

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

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

отвлеклись от темы.
Имхо вы в дебри уже залезли :) Я думаю, что имелось в виду вот что:
«при вызове SomeEvent(this, someArgs) синхронно или асинхронно будет выполнены обработчики, подписавшиеся на событие»
Да, так и есть
НЛО прилетело и опубликовало эту надпись здесь
Учитывая контекст, под event понимается то, что описывается ключевым свойством event языка C#.
под ключевым словом event скрывается нечто среднее между property и field, член класса без каких либо запретов или хитрых механизмов обращения из разных потоков(под «синхронным и асинхронным» иногда подразумевается механизм регуляции запросов к объекту из нескольних потоков).
Если имелось ввиду его поведение в контексте исполнения, то это зависит от реализации(как написал выше bobermaniac) и фантазии.
Ответ просто «да», т.к. value types не имеют отношения к сборщику мусора
А локальные только value types? Ну-ну
Вопрос вообщето про сборщик мусора, а не про локальные переменные
Судя по английскому, писали индусы.
Нет, но и не нейтивы.
What does keyword 'in'?

Так пишут в основном славяне :)
Индусы тоже так пишут. Хотя данный пример сильно славянский. Эхх, да чего говорить, на многих аутсорсинговых сайтах инглиш такой и ничего — набирают заказы, работают…
What does keyword 'in' do? В других вопросах такой ошибки нет, тут как раз опечатка.
НЛО прилетело и опубликовало эту надпись здесь
6 — Не полный ответ, но сойдёт.
7 — Не верно.
9 — Плохо.
10 — Не объект, а член.
13 — Это понятно, но чем тогда (Type)obj отличается от obj as Type?
17 — Не верно.
18 — Не верно.
19 — Не верно.
21 — Не верно.
23 — Не только конкатекация, но сойдёт.
25 — Не верно.
28 — Не верно.
30 — Плохо.
33 — Без комментариев данный ответ не засчитывается.
35 — Не верно.
37 — Не верно.
38 — Плохо.
46 — Не верно.

Итого 34 верных ответа :-)
а комментарии почему не верно?… понятно, что это вопрос больше к Рихтеру, но если вкратце.
> 7 — Не верно.
Важное отличие — экземпляр класса string нельзя менять. Это очень существенно отличие. Это, в частности, означает что если надо передать в функцию изменяемый параметр, то для string, в отличие от других классов, надо указывать ref.

9 — Плохо.
В сателитной сборке локализованные ресурсы, кода нет вообще.

13 — Это понятно, но чем тогда (Type)obj отличается от obj as Type?
as, в отличие от обычного приведения типов, не генерирует исключение.

17 — Не верно.
Это всё детали реализации, а суть проста — An event is a member that enables an object or class to provide notifications.

18 — Не верно.
Разница в том, что event можно вызывать только из самого класса, а поле-делегат откуда угодно.

19 — Не верно.
Вопрос подробно обсосан, ответ — синхронны.

21 — Не верно.
Члены интерфейса не могут быть приватными.

25 — Не верно.
public internal даже не скомпилируется.

28 — Не верно.
Член виден наследникам из той же сборки

30 — Плохо.
Надо написать [return: AttributeDeclaration]. Собственно, аналогично для сборки — [assembly: AttributeDeclaration]

33 — Без комментариев данный ответ не засчитывается.
Либо отвечаем да, либо нет и пишем про реализацию Array.Resize.

35 — Не верно.
У деструктора не может быть модификаторов доступа.

37 — Не верно.
typeof возвращает объект типа Type только для типа, для переменной надовызывать метод GetType()

38 — Плохо.
Marshal.SizeOf работает и для классов. Кроме того, Marshal.SizeOf возвращает не размер в памяти, а размер бинарного представления для интеропа.

46 — Не верно.
Есть InternalsVisibleToAttribute. Не такая дружба как в C++, но всё же дружба.
НЛО прилетело и опубликовало эту надпись здесь
Послушайте, есть разница в реализации, она нам не важна, о ней можно вообще не знать, и разница в использовании, вот её знать надо.
НЛО прилетело и опубликовало эту надпись здесь
>> Зачем знать разницу в поведении вызово, если при попытке скомпилировать вызов event снаружи класса компилятор выдаст приемлемую ошибку?

Ну вот мне в голову не придёт звать event снаружи. Думаю, иметь понимание предназначения лучше, чем ожидать ошибки компилятора.
НЛО прилетело и опубликовало эту надпись здесь
Потому что вы вечно скатываетесь к реализации, совершенно не понимая что контракт гораздоважне. Реализация меняется, контракт — нет.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Если вы передадите Listбез ref в него можно будет добавить элемент, если передадите string без ref в неё нельзя будет добавить символ.
НЛО прилетело и опубликовало эту надпись здесь
Это и называется — immutable
НЛО прилетело и опубликовало эту надпись здесь
Я всего лишь продемонстрировал как immutable может отражаеться на поведении при использовании.
НЛО прилетело и опубликовало эту надпись здесь
Имхо по 7 как раз immutable гораздо чаще выстреливает, чем интернирование. Последнее — по сути особенность реализации (разница в поведении Equal и ReferenceEqual).

А вот immutable грабли неопытных бьют часто и с оттягом.
НЛО прилетело и опубликовало эту надпись здесь
Никто и не заставляет, тест проверяется человеком прямо при кандидате. Если дан «не тот» ответ, то, конечно, правильнее спросить «А не знаете ли вы ещё каких-нибудь отличий», чем ставить минус. Ну и, на крайний случай, всегда можно зачесть пол-балла.
НЛО прилетело и опубликовало эту надпись здесь
Мой вариант ИМХО лучше тем, что его знание чаще нужно.
НЛО прилетело и опубликовало эту надпись здесь
:D

Имхо спор ни о чем — вернее о чем угодно, но не о правильном ответе.

«Критерии истинности», «дать еще один шанс», «а если ...». Собеседование не направлено на выяснение истинности или величия философских взглядов претендента. Оно направлено на быстрый способ определить — подходит кандидат или нет. Многими любимый Спольски говорил — лучше не взять хорошего программиста, чем взять плохого.
ИМХО если начинается такое студенческое нытье — а может вы поставите плюсик за ответ, ну я же что-то ответил или тут очень неоднозначный ответ — сразу в сад, этот человек и с тим лидом будет спорить и со всеми остальными — он только таким нытьем и будет заниматься вместо работы.
НЛО прилетело и опубликовало эту надпись здесь
как вы ловко обо мне выводы все сделали… Прямо как вживю за мной наблюдали…

Вообще удивительно как сообщества подобные хабру приучают людей читать не то что написано, а то что они хотят видеть.

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

г) мне жаль вас, потому что вы читаете не то, что написано, а то что хотите прочитать. Приписываете мне и моему тимлиду различные убеждения, хотя ни одного не встречали в реальной жизни. Наверное забавно жить в такой своей реальности — все сразу и обо всех знаете, на все имеете свое мнении. Жаль что к реальности это имеет очень малое отношение.
НЛО прилетело и опубликовало эту надпись здесь
Ну давайте займемся буквоедством :)
видимо Вы, как и adontz, считаете, что если

если у Вас тим лид тоже полагает

Одно лишь тоже говорит о том что и меня и тим лида вы пытаетесь наградить описанными взглядами (хорошо что через если, т.е. не окончательно попадаете в просак с приписыванием мнений. :) ).

И да, я буквоед-зануда, можно не трудиться мне это сообщать…

PS: про нытье было абстрактно, но ваши споры на тему «кто правее» подразумевались ;)
НЛО прилетело и опубликовало эту надпись здесь
>> это adontz настаивает, что важнее неизменяемость, ничем это не обосновывая.

Я обосную. Есть такая штука как общепринятая терминология, общие ценности и т.д. Если вы обозначаете высоту — W, а ширину — H, то вы не становитесь глупым, вы становитесь проблемным. Если вы не знаете, что Presentation Layer/Business Logic Layer/Data Access Layer — стандартная архитектура по Фаулеру, вас это не делает идиотом, просто вы не впишитесь в команду.
НЛО прилетело и опубликовало эту надпись здесь
а) У меня есть достаточно большой опыт, которым я руководствуюсь.

б) Я ссылаюсь не на авторитеты, а на общепринятые нормы.

Если я вас спрашиваю чем линейка отличается от простой полосы пластика, то можно ответить, что она обычно прозрачная. Но, вообще-то, основное свойство линейки — деления на её поверхности. Если вы со мной не согласны, вы не глупы, мы просто говорим на разных языках и вы лично мне не подходите. Я считаю, что основное отличие string от других классов, его неизменяемость. Весь мой опыт подсказывает, что именно непонимание неизменяемости приводит к ошибкам. Вы считаете иначе? Да на здоровье, но я вас не найму. Понятно, что один вопрос ничего не решает, но по совокупности именно так. Я нанимаю человека в команду, так что должен быть общий базис. Это не собеседование на лучшего разработчика ПО, это собеседование на разработчика, который подходит мне.
НЛО прилетело и опубликовало эту надпись здесь
Конечно. Но, что важнее, часто видел такие ошибки у других.
НЛО прилетело и опубликовало эту надпись здесь
Я совершал не ошибки, а ошибку. Один раз вызвал string.ToUpper() и не понял почему строка не изменилась. Потом, запомнил и как-то ран на сердце не осталось. Но исходя из занимаемых мною должностей, мне часто приходилось делать code review, так что суждение моё достаточно объективное.

А вы, как сами признались, не подходите, вы функциональщик.
А неплохой тест, нубов отсеивать.
Спасобо за тест. Если кому интересно здесь www.infotest.by/ есть много тестов по разным технологиям.
Вопросы с собеседования на должность «C# Compiler».
Вопрос на должность C# Compiler будет из серии «что выведет программа?»

using System;

public class Program
{
	public static void Test<T>(T arg)
	{
		Console.WriteLine("<T>");
	}

	public static void Test(object arg)
	{
		Console.WriteLine("Object");
	}

	public static void Test(string arg)
	{
		Console.WriteLine("String");
	}

	public static void Main()
	{
		Test("String Argument");
		Test<string>("String Argument");

		object x = "String Argument";

		Test(x);

		var y = "String Argument";

		Test(y);
	}
}
Вывела «Follow the white rabbit». Упс, в дверь постучали…
НЛО прилетело и опубликовало эту надпись здесь
Так отвечает плохой разработчик, хороший разработчик понимает как работает перегрузка функций и вывод типов и понимает какой метод вызовется не путём эксперимента. Когда я работал с Си++, там были аналогичные тесты на перегрузку и куда более зубодробительные, если учесть что есть const, ссылки и т.д.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории