Здравствуйте, Vzhyk, Вы писали:
V>И где там про юнит-тесты?
А нигде, но вообще говоря было очень грамотно их предоставить.
Т.е. сразу видно, что человек подошел к задаче грамотно, капитально.
Представьте ситуацию: нужно выбрать из двух претендентов, которые с правились с
задачей на ура, т.е. код удовлетворяет всем условиям, но у одно есть юнит-тесты, а
у другого нет. И тут можно склонить чашу весов в свою пользу.
Я не фанат юнит-тестов, сам их редко пишу (считай не пишу вовсе),
но для собеседования уж постарался бы.
12/6/2013 3:21 PM, Sharov пишет:
> Т.е. сразу видно, что человек подошел к задаче грамотно, капитально. > Представьте ситуацию: нужно выбрать из двух претендентов, которые с > правились с > задачей на ура, т.е. код удовлетворяет всем условиям, но у одно есть > юнит-тесты, а > у другого нет. И тут можно склонить чашу весов в свою пользу.
А еще может быть куча нюансов, почему один подошел, а другой нет. Другой
мог быть банально грамотнее, банально дешевле и т.д. и всякие UT могли
не иметь никакого отношения. А вообще можно сказать и так, человек
зачем-то начал делать то, что не просили, нафига, нужен ли нам такой
"инициативный".
Из обсуждения здесь уже видно, что ТС не очень крутой программист на
фоне некоторых местных (я в С# ничего не знаю и посему доверяю местным
знающим) и вполне возможно, что он не подошел по квалификации. Но, это
простейшая культура и на минимальном уровне, если человек сделал задание
и прислал, ответить ему, даже стандартной фразой (по крайней мере я так
понял пост ТС).
З.Ы. А вообще, насчет тестовых заданий. Я их противник, кроме случая,
давать их выпускнику вуза, если у того нет опыта работы на програмерской
конторе.
З.З.Ы. Помню, сделал одним тестовое задание, прошел, конечно и даже 2
месяца поработал и сделал ноги оттуда. С таким говенным кодом и
настолько же убогой организацией разработки мне не приходилось ни до ни
после работать. Ну и еще обычно самые говенные конторы тестовые задания
просят, но этим говоришь досвидания сразу же. Одни вообще ругаться по
телефону стали (да, встречаются и такие), когда я сказал, что мне
выполнять их тестовое задание не интересно.
Здравствуйте, Vzhyk, Вы писали:
V>Но, это V>простейшая культура и на минимальном уровне, если человек сделал задание V>и прислал, ответить ему, даже стандартной фразой (по крайней мере я так V>понял пост ТС).
ТС и ответили, мол не то. Ну не построчно же с ним разбирать код. Банально
может быть некогда. Если ТС грамотный человек, то он придет на форум программистов,
покажет задачу, свое решение, и ему укажут на косяки. И это кстати, будет
лучше, т.к. больше народу посмотрит на код.
V>З.Ы. А вообще, насчет тестовых заданий. Я их противник, кроме случая, V>давать их выпускнику вуза, если у того нет опыта работы на програмерской V>конторе.
S>Да и сами тесты помогли бы Вам лучше понять код и требования.
Поддерживаю, я бы еще написал сравнительные нагрузочные тесты.
Без тестов самому не понятно, делает ли оно то, что ожидается.
Уж если взялся, то писать как для себя.
Хотя, сам бы стал делать задание, только если бы очень хотелось именно в эту кантору.
Здравствуйте, Vzhyk, Вы писали:
>> ТС привел описание задачи, Ваш КО. V>И где там про юнит-тесты?
Ну про юнит тесты действительно явно сказано не было.
Но вот эта строчка
M>Программа должна содержать пример использования коллекции с идентификатором ключа в виде пользовательского типа (т.е. Id в ключе – UserType, объекты UserType должны сравниваться по значению).
однозначно содержит требование написать не только коллекцию, но и код ее использующий.
А уже UT это будет или main совсем не важно.
И именно в этом коде должен появиться UserType как параметр(может в # используется другой термин но смысл я думаю понятен) обобщенной коллекции.
А у ТС UserType — это тип поля в MyId, а MyId используется внутри коллекции.
В общем все это больше похоже на фэйк или загадку типа "кто найдет больше несоответствий условиям задачи"
Большое спасибо всем за уделенное этой задаче время.
Действительно куча ошибок. Наверное и правда, дело в том, что после тяжелого рабочего дня и недели в целом.
По сути главная проблема — неверная трактовка задания как такого, ну и отсутствие code review за самим собой, так как делал достаточно быстро.
Отдельное спасибо Хэлкар,Vzhyk,mogikanin,Ромашка.
Кстати, в sln был включен проект с UT. Понятно, что так как условие задачи было воспринято мной неверно, то и тесты некорректны.
В общем, еще раз всем спасибо.
На этом тему можно считать закрытой.
/// <summary>
/// Проверяем возможность заполнить коллекцию
/// </summary>
[TestMethod]
public void TestMethod1()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
Assert.AreEqual(9, collection.Count);
}
/// <summary>
/// Проверяем реакцию на вставку дубликата
/// </summary>
[TestMethod]
public void TestMethod2()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
MyElement newElement = new MyElement()
{
Id = new UserType() { Content = 1 },
Name = String.Format("Unit - {0}", 1 )
};
int initCount = collection.Count;
collection.Add(new MyId(newElement), newElement);
Assert.AreEqual(initCount, collection.Count);
}
/// <summary>
/// Проверяем работает ли поиск по Id
/// </summary>
[TestMethod]
public void TestMethod3()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
MyElement lostAndFound = collection.GetElementById(new UserType() { Content=5 });
Assert.AreNotEqual(null, lostAndFound);
}
/// <summary>
/// Проверяем работает ли поиск по Name
/// </summary>
[TestMethod]
public void TestMethod4()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
MyElement lostAndFound = collection.GetElementByName("Unit - 7");
Assert.AreNotEqual(null, lostAndFound);
}
/// <summary>
/// Проверяем работает ли поиск по id или name
/// </summary>
[TestMethod]
public void TestMethod5()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
MyElement lostAndFound = collection.GetElementByIdOrName("Unit - 5");
Assert.AreNotEqual(null, lostAndFound);
}
/// <summary>
/// Потокобезопасность - проверка одновременной вставки
/// </summary>
[TestMethod]
public void TestMethod6()
{
#region Fake
MyCollection<MyId, MyElement> collection = new MyCollection<MyId, MyElement>();
for (int i = 1; i < 10; i++)
{
MyElement el = new MyElement()
{
Id = new UserType() { Content = i },
Name = String.Format("Unit - {0}", i)
};
MyId mid = new MyId(el);
collection.Add(mid, el);
}
#endregion
MyElement newElement = new MyElement()
{
Id = new UserType() { Content = 10 },
Name = String.Format("Unit - {0}", 10 )
};
int initCount = collection.Count;
Action<object> action = (object obj) =>
{
collection.Add(new MyId(newElement), newElement);
};
t.Task t1 = new t.Task(action,"thread1");
t.Task t2 = new t.Task(action, "thread2");
t.Task t3 = new t.Task(action, "thread3");
t1.Start();
t2.Start();
t3.Start();
t1.Wait();
t2.Wait();
t3.Wait();
Assert.AreEqual(initCount + 1, collection.Count);
}
Не было просто серьезной мотивации для решения более серьезного, если честно.
Так как делалось все довольно быстро — то куда ж без хаоса.
На счет не выполняется — это Вы зря. Я же только описание классов привел.
На счет последнего вопроса — да. А Вы? Никогда не доводилось писать быстро? Или даже в таких случаях у Вас все идеально? )))
N>Полкода лишние и он не делает то, что должен. Даже близко. Много очевидных опечаток. Общий хаос в коде. N>Рекомендую внимательнее прочесть задание и сделать значительно больше усилий над разработкой. N>А вы уже работали программистом?
M>Этот вариант решения, как видно, не понравился проверявшему. M>Буду признателен, если "ткнете носом" в ошибки. Понимаю, что, возможно подошел к решению довольно формально, но по требованиям вроде все реализовал. Или чего-то не так понял.
Здравствуйте, mig84, Вы писали:
M>Не было просто серьезной мотивации для решения более серьезного, если честно. M>Так как делалось все довольно быстро — то куда ж без хаоса.
Здесь проглядываются довольно простые ошибки, которые опечатками не объяснишь. Код слабоват.
M>На счет последнего вопроса — да. А Вы? Никогда не доводилось писать быстро? Или даже в таких случаях у Вас все идеально? )))
А зачем тогда было отправлять? Если неохота тратить своё время, то лучше не делать тестовое задание. Но взяться делать и при этом вполсилы это как то совсем странно. Либо попадёшь в плохую контору (где требуют тестовые задания несмотря на то, что здесь все стонут, но при этом не проверяют их, либо их устраивает посредственное качество), либо гарантированно потеряешь время.
Здравствуйте, alzt, Вы писали:
A>Здравствуйте, samius, Вы писали:
A>тоже про equals напишу.
A>
A>public override bool Equals(object obj)
A>{
A> if (!(obj is MyElement))
A> {
A> MyElement el = (MyElement)obj; //NULL
A> return Id == el.Id && Name == el.Name; //БАБАХ new NullReferenceException();
A> }
A>
Добавл комменты.
A>Может я совсем C# уже забыл, но что вернёт obj is MyElement если obj имеет тип MyElement?
Ты ничего не забыл.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, Философ, Вы писали:
Ф>>Здравствуйте, alzt, Вы писали:
A>>>
A>>>public override bool Equals(object obj)
A>>>{
A>>> if (!(obj is MyElement))
A>>> {
A>>> MyElement el = (MyElement)obj; //NULL
A>>> return Id == el.Id && Name == el.Name; //БАБАХ new NullReferenceException();
A>>> }
A>>>
Ф>>Добавл комменты. S>По-моему они еще больше запутывают. Это для прикола, или это прогнозируемые значения и события?
И первое, и второе.
00 if (!(obj is MyElement)) //условие истинно, если obj не является типом MyElement — восклицательный знак всё портит
10 MyElement el = (MyElement)obj; // в шарпе это вообще не выполнится — вывалится с InvalidCastException. Чтобы выполнилось можно кастовать с помощью оператора as
10 MyElement el = obj as MyElement; //а вот так выполнится, el будет равен NULL
20 return Id == el.Id && Name == el.Name; //оращение к полю неинициализированного объекта вывалит исключение NullReferenceException()
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>Здравствуйте, samius, Вы писали:
S>>По-моему они еще больше запутывают. Это для прикола, или это прогнозируемые значения и события?
Ф>И первое, и второе.
Ф>00 if (!(obj is MyElement)) //условие истинно, если obj не является типом MyElement — восклицательный знак всё портит
Ф>10 MyElement el = (MyElement)obj; // в шарпе это вообще не выполнится — вывалится с InvalidCastException. Чтобы выполнилось можно кастовать с помощью оператора as
С этим согласен. Но потому как в коде не as, обсуждать остальное смысла нет.