Собеседование разработчика

от автора

Техническое собеседование – практически неотъемлемый атрибут трудоустройства любого разработчика, а для старших разработчиков – проведение их (собеседований) ещё и чуть ли не повседневная обязанность. Но как за короткий срок (в идеале 20-30 минут) составить у себя более менее приемлемое представление о реальном опыте соискателя?

Помню, как меня впервые попросили прособеседовать по WPF молодого человека – я несколько часов составлял список того что стоит спросить (и перепроверял ответы, чтобы самому не ударить лицом в грязь) чтобы хоть с какой-то то долей уверенности потом сказать, нужен нам в компании такой человек или нет. И вот, вооружившись 10-15 вопросами, я вхожу в переговорную, представляюсь, задаю пару общих вопросов и между прочим уточняю:
— А сколько у вас лет опыта разработки с использованием WPF?
— Я не знаю WPF….
— …
Этот неловкий момент когда ты понимаешь, что предусмотрел всё, кроме самого очевидного…

Другой, не менее неожиданный для меня поворот был, когда в CV соискателя был указан опыт разработки 5 лет и перечислены куча интригующих описаний проектов, а по факту, человек с трудом смог объяснить, чем отличаются ссылочные типы от значимых, а про сборку мусора сказал, что знает лишь то, что о памяти в .Net думать не нужно…

Что же можно спросить, чтобы можно было положиться на ответ, как на что-то значимое?
— Спрашивать, какие книги он и по сколько раз прочитал? Но заученные формулировки не говорят о том, что человек способен решать реальные задачи, постановка которых отличается от книжных и порой требует отклонения от общих принципов разработки по тем или иным причинам.
— Выписать все технические нюансы среды и спрашивать о них? Но по правде говоря, кому хоть раз пригодилось знание о том, как работает сборка мусора (которая к тому же и меняется от версии к версии) и сколько там поколений? Я не говорю, что это лишнее знание – отнюдь, но знание или незнание этой особенности не позволят определить «качество» разработчика.
— Просить показать пример кода? Но какой код вам покажут? Сколько людей его уже правило? В каких условиях он был написан? Что если эти блестящие 300 строк писались месяц под шум прибоя атлантического океана в сезон дождей? Сможем ли мы потом воссоздать «рабочую» атмосферу, чтобы получить следующие 300 блестящих строк?

Я хочу поделится своей идей и услышать конструктивную критику такого подхода к проведению собеседований. Моя идея заключается в том, чтобы показывать «СВОЙ» код и слушать. За вечер я набросал пример ужасного кода, включив в него самые распространённые «ошибки». Я ожидаю, что старший разработчик, с реальным опытом разработки от 4 лет, должен идентифицировать более 80% процентов ошибок и указать на существующие проблемы в гипотетической архитектуре.

И так, собственно код:

1	using System; 2	using System.Collections.Generic; 3	  4	namespace App.Services 5	{ 6	    public enum LoginResult 7	    { 8	        Unknown = 0, 9	        Success = 1, 10	        WrongLogin = -1, 11	        WrongPass = -2, 12	        Error 13	    } 14	  15	    public class LoginService 16	    { 17	        public string LastError = string.Empty; 18	  19	        /// <summary> 20	        /// Allow to login new user 21	        /// </summary> 22	        /// <param name="login">login</param> 23	        /// <param name="password">password</param> 24	        /// <param name="asAdmin">asAdmin</param> 25	        /// <returns>login result</returns> 26	        public LoginResult Login(string login, string password) 27	        { 28	            List<Login> dbLogins = new List<Login>(); 29	            try 30	            { 31	                dbLogins.AddRange( 32	                    DAL.GetItems<Login>( 33	                    "select * from db.Login where Name='" + login + "'")); 34	            } 35	            catch (Exception ex) 36	            { 37	                lock ((object)777) 38	                { 39	                    LastError = ex.Message; 40	                } 41	                throw ex; 42	            } 43	            if (dbLogins.Count < 1) 44	            { 45	                return LoginResult.WrongLogin; 46	            } 47	  48	            var prevUser = App.CurrentUser; 49	            App.CurrentUser = dbLogins[0]; 50	            if (password.CompareTo(App.CurrentUser.Password) != 0) 51	            { 52	                App.CurrentUser = prevUser; 53	                return LoginResult.WrongPass; 54	            } 55	  56	            var log = System.IO.File.AppendText(App.LogFile); 57	            log.WriteLine("New user loggined. Login=" + App.CurrentUser.Name); 58	  59	            if (!(bool)((EventService)App.Service).SendWithConfirm(prevUser)) 60	            { 61	                log.Write("Error sending to user."); 62	            } 63           64	            GC.Collect(); 65	            GC.Collect(); 66 67	            return LoginResult.Success; 68	        } 69	    } 70	} 

Ошибки ( номер строки и описание, которое я ожидаю услышать от соискателя):
12 – Значение для «Error» будет «-1», что продублирует уже существующее и не позволит в будущем отличить одно от другого.
17 (1) – Public field. По правилам хорошего тона не рекомендуется делать поля публично доступными.
17 (2) – Запись в переменную далее по коду «реализована» через lock, но внешний потребитель может и не знать о том что обращение к переменной следует синхронизировать с кем-либо.
20 – Бессмысленные комментарии.
24 – Комментарий не соответствующий действительности.
28 – Публичный метод принял параметры из вне, но не выполнил проверку на их корректность (как минимум на null).
32 – Сильная связанность.
33 (1) – Потенциальная место для использования SQL инъекции. Так как для формирования запроса используется конкатенация а не параметры. А во вторых – не параметризованные запросы не кэшируются сиквел сервером (если СУБД сиквел).
33 (2) – Подобный стиль формирования запросов «привязывает» приложение к конкретной СУБД).
33 (3) – Конкатенация строк таким образом не самое эффективное решение.
35 – По правилам хорошего тона следует перехватывать ошибки, которые могут быть обработаны, а не всё подряд.
37 – Этот lock не будет работать.
39 – Бессмысленное значение в переменной и никакой пользы для разработчиков при диагностики.
41 – Актуальный стэк трйс, который мог бы быть полезен при диагностике ошибки безвозвратно потерян при таком порождении исключения.
49 (1) – Разрушение состояния приложения, так как при ошибке ниже (null пароль) в поле текущего пользователя будет уже новый логин.
49 (2) – Неявная бизнес логика. Почему отсекли другие логины?
50 (1) – Пароль не проверен на null и может быть исключение которое приведёт к разрушению состояния приложения.
50 (2) – Пароль хранится и используется в открытом виде.
53 – По правилам хорошего тона – не следует сообщать столь подробную информацию о причинах ошибки аутентификации.
56 (1) – Отсутствие продуманного механизма логирования как такового.
56 (2) – Открывается поток, но его закрытие и уничтожение не выполнены, данные могут быть и не записаны в конечный файл.
56 (3) – Операция работы с файлами может породить исключение, которое уровнем выше может быть трактовано как ошибка аутентификации, хотя по факту – логин уже прошёл.
57 – Бессмысленная информация, которая никак не упростит жизнь анализирующего лог файл, если он вдруг будет создан и кому ни будь потребуется.
59 (1) – Кроме связанности, вложенные вызовы с «завышенными» ожиданиями касательно возвращаемого результата.
59 (2) – Неочевидная бизнес логика.
61 – Бессмысленная запись в лог.
64,65 – Признак больших проблем с памятью в приложении. (Также я ожидаю услышать почему именно два вызова подряд и почему так делать всётаки не стоит)

Может, кто-то уже применял такой подход и может поделиться своим опытом?

ссылка на оригинал статьи http://habrahabr.ru/post/199136/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *