Объясните, насколько объективно мне дали ответ

Прислали мне письмо из одной фирмы.


спасибо за Ваше резюме.
Сразу говорю что для работы у нас нужны хорошие навыки программирования на C#.
Если Вы считаете что ваши знания на уровне — попробуйте сделать тестовое задание.
Ориентировочное время выполнения — до 6 часов.
Конечно, какого уровня я понять не смог.

В первом же письме было тестовое задание.
Сделал я его за 2.5 часа, хотя и этого времени не было, и мои предложения о просмотре похожего задание отвергли.

Задание:

Написать программу для поиска файлов по заданным критериям.

Программа должна быть реализована на Windows Forms.

Основные параметры поиска:
— Стартовая директория (с которой начинается поиск)
— Шаблон имени файла (должна быть возможность использовать шаблонные символы * и ? как в Windows)
— Текст содержащийся в файле. Может поддерживаться только конкретная фраза
— Ограничения на размер файла: больше / меньше / равен заданного размера
— Огарничения по аттрибутам: искать толькос определенными аттрибутами (Системный, Скрытый, Архивный)
— Флаг контролирующий нужно ли обрабатывать поддиректории. Если установлен значит надо искать файлы как в стартовой так и во всех вложенных директориях.

Все параметры применяются по правилу И — т.е комбинируются вместе для более узкого поиска.

На главном окне также должен быть элементы:
1. отображающий какой файл обрабатываеться в данный момент (имя файла с полным путем)
2. отображающий список найденных файлов (полный путь)
3. Отображающий колличество обработаных файлов и прошедшее время

Эти элементы должны обновляться в реальном времени. Т.е. обработка файлов должна вестись в отдельном процессе.

Так же надо реализовать следующие команды:
— Начать поиск
— Остановить поиск (т.е. поиск должен быть прерван в любое время а не только когда обработает все файлы)
— Сохранить результаты — записывает в текстовый файл все найденные файлы с полными путями.
— Сохранить парамаетры — все введенные параметры должны сохраняться в файл рядом возле исполняемого файла. Тип файла может быть любым.
При запуске программы настройки считываться и устанавливаються автоматически.

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

1. Нельзя искать без поиска по содержимому. Т.е. он это сделал обязательным
Мой ответ: смотрим пунк задание «Основные параметры поиска:» -> «Текст содержащийся в файле. Может поддерживаться только конкретная фраза»
2. Не экономная настройка размера файла (он парсит введенную строку, хотя есть контрол специально для ввода чисел)
Мой ответ: Конечно, использовать контрол, который явно при каждом нажатии делает проверку куда экономние, чем сделать один раз в конце ввода. Может быть эргономичней использовать спец. контрол, но не как не экономичнее.
3. Кнопка старт не блокируется, поэтому можно хоть 10 потоков запустить и потом будет 10 дубликатов в результате
Мой ответ: Опять смотрим в задание, в котором не слово о блокировке, может быть человеку хочется, не по одним параметрам искать, а по не сколько, он запускает в начале один потом другой, потоки друг с другом не как не конфликтуют.
4. При старте не очищаются результаты прошлого поиска
Мой ответ: Да, по сути может быть это и нужно было бы, но если посмотрим в верхний пункт, то можно понять, что в задании этого не было и пользователь собирает пакет данных. Моя ошибка в том, что нужно было предусмотреть кнопку «Очистить».
5. Нельзя искать по всем типам файлов, только по какому-то конкретному. Кстати два типа файла сразу, нельзя выбрать
Мой ответ: Типы файлов, хм, маски поиска работают, может они о атрибутах? Если так, то смотрим т3 и видим в пункте «Основные параметры поиска:» -> «Огарничения по аттрибутам: искать толькос определенными аттрибутами (Системный, Скрытый, Архивный)». Ключевое словосочетание «толькос определенными».
6. Настройки сохраняются, но куда-то в виндовую папку, т.к. он даже не указывает путь для сохранения, только имя файла
Мой ответ: да, это правда. я использую kernel32 и он где его приютил у себя, надо было полный путь указать, зато при перемещении программы конфиг сохраняется. Хотя есть и плохая новость, будет проблема с правами доступа =(.
7. Внешний вид программы неопрятный, результата поиска не вызывают удовлетворения
Мой ответ: не знаю, что ответить, наверное так и есть.
8. Также неопрятный исходный код

Проект: depositfiles.com/files/yhf11t216

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Давайте посмотрим цель тестового задания — сгенерировать ответ "Да"/"Нет" "Подходит"/"Не подходит" — а не говорить, что правильно, что не правильно. Возможно от вас ожидают работу над ошибками?

Если «да» то исправьте быстренько и отправьте еще раз — это работодатели очень ценят.

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

Хотя детали требуют труда — «вылизать» до идеала даже маленький проект за 6 часов — это маловато времени.

Мой совет. Разберись в ошибках, Андрей Горбоконь написал много толкового по этому поводу. Исправь баги, усвой ошибки. В результате получишь:
1. Какой никакой «боевой» опыт.
2. Получишь новые знания.
3. У тебя будет проект, который можно и в портфолио вставить.

Иначе это будет просто впустую потраченное время — и работу не нашел, и ничего полезного для себя из ситуации не вынес.

Подобного рода проекты действительно можно (нужно) вставлять в портфолио?!

Если в письме не указано обратное, почему нет?

Печенкой чую — супер пупер решение будет, если использовать доступ к Indexing Service (я не знаю, как это делается, но по-идее, это возможно). Этот сервис как раз и каталогизирует содержание файлов, и конечно, он должен работать, и индексы перед запуском должны быть построены, и у тебя сразу есть возможность узнать его содержимое, не читая его

0_щ — не чего не понял. Но пробью по «Indexing Service»

Написал пример на java. Потратил 3.5 часа.

jtinycad.googlecode.com/...eByTemplate.zip

внешний вид:

jtinycad.googlecode.com/.../screenshot.png

Только не понятно как в java проверять атрибуты файла :)

Эти элементы должны обновляться в реальном времени. Т.е. обработка файлов должна вестись в отдельном процессе.

Для этой задачи UI и так будет обновляться в реальном времени, даже если реализацию поиска сделать в потоке формочки (рекурсивный поиск, с использованием FileInfo и DirectoryInfo, а также чтение потока, ресурсов отжирает очень мало — интерфейс обновится без задержек). А путание автором задания понятий «процесс» и «поток» — жирный минус в адрес компании. Задача — минут на 40, с вылизанными исходниками и прекрасной формочкой.

Я 40 минут только накидывал и обзывал контролы.

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

Чтобы установить из другого потока свойство элемента управления, который порожден в потоке формы — нужно использовать делегат: проверять свойство InvokeRequired элемента управления, и если он в true — вызывать его метод Invoke(делегат_с_соотв_сигнатурой), который установит свойство. Иначе выскочит exception.
Либо создавай свои события в реализации поиска, который крутится в отдельном потоке, а на форме будет подписчик, который по соотв. событиям будет обновлять UI (что, ИМХО, более предпочтительнее).
Ну а для сохранения параметров поиска — для этого можно написать сериализуемого Хранителя (тупо класс с автоматическим свойствами), который можно сериализовать (сохранять параметры на диск) и соответственно десериализовать (чтобы параметры считывать).

«Для этой задачи UI и так будет обновляться в реальном времени»

Значит не будет «и так будет обновлять».

Наверное, хотели выяснить — умеешь ли ты работать с потоками, поэтому захотели, чтобы ты сделал многопоточно. ИМХО не секрет, что если у тебя в основном потоке крутится ресурсоемкая реализация, которая устанавливает свойства элементов управления, после которых они должны быть визуально обновлены (например, свойство Text), или устанавливается другой тип курсора — они перерисовываются со скрипом: хоть пользуйся извратом Application.DoEvents, хоть control.Invalidate — визуально отрефрешатся, когда на низком уровне контролу прийдет соотв. системное сообщение. А пока крутится ресурсоемкая реализация — основной поток ею занят, ему — не до обработки системных сообщений. Посему такие штуки выносят в отдельный поток. Можешь поэкспериментировать с бесконечным пустым циклом в UI потоке, и в отдельном, и увидишь разницу. Вот клик мышкой, драг формы, и т.д. — это соотв. системные сообщения, которые обрабатываются на уровне WinAPI формочкой и ее чайлдами (spy++ в помощь — утилита, которая может на низком уровне показать, какие системные сообщения «бомбардируют» твою форму в настоящий момент). И вот когда ты видишь сообщение в тайтле формы «Not responding» — это значит, что сообщения о твоих действиях идут, но форма не в состоянии их обработать, потому что работает ресурсоемкая реализация. А перенесешь ее в отдельный поток — форма всегда сможет обрабатывать системные сообщения, и не «замерзать»

Да, действительно. Значит еще на одну дурную привычку у меня будет больше :)

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

Хаха, я убил 2 дня на поездку в Google как-то. Да, чего-то не срослось после 5 собеседований в течение целого дня, хотя и казалось, что отвечал и решал задачки там хорошо.

Сдается мне, что этой компании до Гугла далековато )))

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

Ориентировочное время выполнения — до 6 часов.

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

Нет, нет. Время засекал лично я.

По UI:
1) Выравнивание и автоотступ по умолчанию включены — почему бы не воспользоваться?
2) Аттрибуты файлов -
невозможно выбрать более одного,
есть возможность ввести неправильное значение — в этом случае приложение «падает»,
забиты хардкодом в контрол (представление и данные не разделены)
3) Start/Stop — логика не интуитивная -
Start может сделать сколько угодно новых сессий поиска (естественно неразделяемых между собой)
Stop останавливает НЕ все сессии (как ни странно)
4) Save result — сохраняет в файл, нейм которого захардкоджен, откуда пользователь узнает где сохранены результаты?

5) Save property (сохранить свойство?) — опять же ini файл, в нем пользователь черт ногу сломит — натройки типа ComboBox1 не дают никакого понимания

6) Max — введите «-42» — ищет и находит, странно? — это все magic numbers и сомнительные проврки при поиске
7) Equality — точный размер? единицы измерения? введите «42» и запустите поиск, у меня файлов размером в 42 байтов нет, но как понять был ли начат поиск, интерфейс на мой клик никак не реагирует
8) Search text — ищет замечательно " " (пробел), но не сохраняет настройки, опять же недостаток ini файлов
9) Current file: process is completed — сэкономили на одной лейбле?
10) Past time: тоже самое, что и equlity — измерение времени в абстрактных единицах
11) Основное окно:
неуправляемо, как уже было сказано, т.е. провести повторный поиск с другими параметрами нереально — не разберешь результатов

не изменяемый размер, нет горизонтального скролла, таким образом, файлы, пути которых длинее окошка — просто не найти

По коду:
0) Все в кучу — нет методов как таковых, только Event handlers, т.е. найти место, где реализована конкретная логика просто нереально

1) Generic Exception handling:

catch (Exception) { }
Я этого в упор не понимаю.
2) Об ООП вообще не идет речь, повторное использование кода даже на базовом уровне невозможно,
все что можно было захардкодить — захардкодили.

4)

if ((sender as CheckBox).Checked)
А если все таки не CheckBox — NullReferenceException, сли 100% уверены, что Checkbox — тогда приведение типов
5)
в вашем случае недопустимо — в ComboBox можно ввести любой текст
var fileAttributes = (FileAttributes)comboBox1.SelectedItem;
6) m_thread — одна переменная потока на все потоки, таким образом все потоки у вас «утекают», а управляете, если это так можно назвать, только последним

7) Заключать весь метод полностью в try с пустым catch — не вижу смысла — т.е. если что-то пошло не так — закругляемся и выходим.

Резюме: скажите спасибо, что вообще дали ответ, провести полный код-ревью и указать на ВСЕ ошибки — стоило бы прилично времени, того человека, который вас проверял, больше чем вы потратили на написание этого проекта

Спасибо, реально ужасно.

До этого никто никогда мой код не проверял, были клиенты, а клиентам нужно «что бы работало».

Баз обид.

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

Те претензии которые вам выставили вполне правомерны — именно по таким пунктам можно отличить программиста разработчика software engineer’а от кодера гуано-кодера (у которого проблема в ДНК) или джуна (у которого еще мало опыта).

Денис, вот что я думаю.. Тестовые задания — это в 80% случаев способ эффективно слить (в оставшихся 20% дать еще один шанц) слабенькому претенденту на вакансию. Вы посмотрите на задание, оно обо все и не о чем сразу, как бы уже есть кучя деталей, но в рецензии на задание выясняется что неменьшую кучю деталей они вам предлагали домыслить самим (в том числе и UI/UX), чего вы не сделали... Если бы они реально были в вас заинтересованы, то они бы не тратили ваше и свое время вот на такой вот бред. Но вы не воспринемайте этот опыт негативно, во-первых вы таки что-то написали, а значит стали немного опытней, а во-вторых, вы теперь знаете что может сыграть не в вашу пользу и на что стоит обратить внимание если опять что-то такое снова попадется. Все что не сделано, все к лучшему ;-)

А вот и нифига, есть конторы в которых тестовое задание предлагается всем, вне зависимости от портфолио. Харьковский Геймлофт, например.

Гадаю, об’єктивно. Вони дали типове технічне завдання, в якому задачу не важко знайти серед купи деталей. Окрім того дуже важко написати всі потрібні деталі, легше побачити програму і вдосконалити її, що зазвичай просто включають в оцінку. І, треба помітити, тут включили: Ви ж зробили задачу так як зробили за 40% часу. Інша справа, що Ви могли зробити як їм хотілось, якби були попереджені.

Взагалі, судячи з їхніх коментарів, їм потрібен розробник фронтенду. Принаймні у тому числі фронтенду. Особливо судячи з пункту 7. Можливо, це не Ваша спеціалізація?

За окремими пунктами:

1 — мені здається «тільки визначена фраза» означає відсутність підтримки регулярних виразів і шаблонів взагалі. Принаймні, я так зрозумів, коли читав ТЗ, хоча і з другої спроби.
3 — це можна назвати мегафічею, але без відповідного інтерфейсу для керування всіма пошуками це все ж таки баг. Гадаю, зупинити потік пошуку після запуску наступного зараз неможливо (Mono у мене не встановлене, тому роблю припущення).

5 — «тільки визначені» означає «тільки відмічені користувачем» і не означає «тільки з одним визначеним атрибутом». В задачі не вказано, але це знову ж тест на те, чи потрібно буде Вам вказувати на всі деталі.

frontend — в winfroms точно нет.

Остановить потоки можно, остановятся сразу все.

Регулярные выражения в части где подойдет обычный IndexOf использовать не вижу нужды.

Хорошо, но это же все не так принципиально,в реальности, это ещё перепроверять будут другие программисты.

> frontend — в winfroms точно нет.

Вибачте за веб-термінологію. GUI я мав на увазі.

> Остановить потоки можно, остановятся сразу все.

Отже це таки фіча. Тоді до логіки зауважень немає, лише до інтерфейсу.

> Регулярные выражения в части где подойдет обычный IndexOf использовать не вижу нужды.

Ну, по-перше вони саме це і написали, а по-друге у пошуку я час від часу користуюсь регулярними виразами, тому тут вони просто спростили Вам задачу.

> Хорошо, но это же все не так принципиально,в реальности, это ещё перепроверять будут другие программисты.

Це зрозуміло, але чим менше потрібно часу витратити на рев’ю, тим менше коштує розробка.

Спасибо, я всё понял и учел.

Регулярные выражения в части где подойдет обычный IndexOf использовать не вижу нужды
Регулярные выражения как раз и нужно использовать для поиска, чтобы на порядок повысить его скорость
Вот не знаю, как же это реализовываеться?

мне кажется это не так..

Ви говорите про швидкість досягнення результату користувачем?

www.google.com.ua/...280&bih=707

Чем больше файл — тем медленнее работает indexOf. Но нужно правильно задавать параметры поиска по регулярным выражениям.

А, навіть так. Ну, регулярний вираз з одних констант можна скомпілювати у оптимальний варіант, я просто очікував, що IndexOf буде працювати не повільніше (Mono не бачив, сорі).

я по блокам достаю информацию и проверяю indexof мне же не нужно найти кол-во совпадений, а только одно вхождение.

RegExValidate(FileBuffer, «Vovan»);

public static bool RegExValidate(string text, string regex)
{
if (!regexCache.ContainsKey(regex))
{
Regex compiledRegex = new Regex(regex,RegexOptions.Compiled || RegexOptions.Multiline);
regexCache.Add(regex, compiledRegex);
}
return regexCache[regex].IsMatch(text);

}

Разовая инициализация с параметром Compiled занимает времени несколько дольше, но перформанс, по сравнению с обычным регексом выше раз в 10. А буфер для поиска дело в том, что у тебя может быть в пределах 2 Гб (если не ошибаюсь — такой макс. размер String). Ну только если файл больше (фильм лежит на диске) — это обязательно нужно обрабатывать. Либо сразу считывать файл порциями, чтобы избежать экспешена, что, конечно, дольше

Еще забыл параметр обязательный — IgnoreCase

ух что это форматирование намутило тут...

без форматирования

1. Нельзя искать без поиска по содержимому. Т.е. он это сделал обязательным
Мой ответ: смотрим пунк задание «Основные параметры поиска:» -> «Текст содержащийся в файле. Может поддерживаться только конкретная фраза»
2. Не экономная настройка размера файла (он парсит введенную строку, хотя есть контрол специально для ввода чисел)
Мой ответ: Конечно, использовать контрол, который явно при каждом нажатии делает проверку куда экономние, чем сделать один раз в конце ввода. Может быть эргономичней использовать спец. контрол, но не как не экономичнее.
3. Кнопка старт не блокируется, поэтому можно хоть 10 потоков запустить и потом будет 10 дубликатов в результате
Мой ответ: Опять смотрим в задание, в котором не слово о блокировке, может быть человеку хочется, не по одним параметрам искать, а по не сколько, он запускает в начале один потом другой, потоки друг с другом не как не конфликтуют.
4. При старте не очищаются результаты прошлого поиска
Мой ответ: Да, по сути может быть это и нужно было бы, но если посмотрим в верхний пункт, то можно понять, что в задании этого не было и пользователь собирает пакет данных. Моя ошибка в том, что нужно было предусмотреть кнопку «Очистить».
5. Нельзя искать по всем типам файлов, только по какому-то конкретному. Кстати два типа файла сразу, нельзя выбрать
Мой ответ: Типы файлов, хм, маски поиска работают, может они о атрибутах? Если так, то смотрим т3 и видим в пункте «Основные параметры поиска:» -> «Огарничения по аттрибутам: искать толькос определенными аттрибутами (Системный, Скрытый, Архивный)». Ключевое словосочетание «толькос определенными».
6. Настройки сохраняются, но куда-то в виндовую папку, т.к. он даже не указывает путь для сохранения, только имя файла
Мой ответ: да, это правда. я использую kernel32 и он где его приютил у себя, надо было полный путь указать, зато при перемещении программы конфиг сохраняется. Хотя есть и плохая новость, будет проблема с правами доступа =(.
7. Внешний вид программы неопрятный, результата поиска не вызывают удовлетворения
Мой ответ: не знаю, что ответить, наверное так и есть.
8. Также неопрятный исходный код

Мой ответ: вот как знал нужно было использовать #region-ы хотя наверное проблема не в этом.

Ну нельзя же заниматься буквоедством! Есть ведь позиция здравого смысла. Представь себе, что это — не тестовое задание, а реальное ТЗ от заказчика. Если ты ему такие же отписки будешь слать — это может быть чревато боком.

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

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

Вот, например, не сказано ведь, что программа должна прекращать поиск и закрываться при нажатии на кнопку закрытия формы, это ведь само собой разумеещееся? А может, поиск нужно завершить явно, блокируя закрытие в Form_Closing, а потом уже только разрешить закрытие формы, потому что обязательно нужно сохранить результат явно? И таких моментов в рабочей ситуации — морее

Поэтому «сухих» клиентов я сразу отшиваю.

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

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

попробуй посмотреть на это со стороны пм/техлида решающего брать тебя или нет — Реальный задачи будут сформулированы еще хуже чем это тестовое, а твое решение прийдется выдавать уже кастумеру. а накодил ты явно на "удовлетворительно"( в смысле трояк на пятибальной системе), а это вызовет потом кучу доделок, багов и т.д. При этом ты даже не понимаеш в чем проблема.

возьмем один пункт

6. Настройки сохраняются, но куда-то в виндовую папку, т.к. он даже не указывает путь для сохранения, только имя файла

Мой ответ: да, это правда. я использую kernel32 и он где его приютил у себя, надо было полный путь указать, зато при перемещении программы конфиг сохраняется. Хотя есть и плохая новость, будет проблема с правами доступа =(.

Тоесть ты вроде понимаеш что проблемы возникнут. Точней такое решение в реальности отправить заказчику нельзя — не все работают под админом, а если программа установлена, то обычный юзер с большой вероятностью с ней работать не сможет. Но проблема в тут в том, что ты вроде понимаеш проблему, а решать ее не пробуеш (например Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ). А такого человека еще учить и ревьювать код за ним нужно. Не на всех проектах этим есть возможность заниматься, вот и не взяли.

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

Подписаться на комментарии