Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

EBojilova avatar EBojilova 330 Точки

[Exam] KPK C# 23 August 2015

Явно аз съм най-нетърпеливата винаги и пускам тема след всеки изпит. Решението, което съм приложила минава нулеви тестове, но не е проверено още в judge. 

Много ме затрудни този изпит- с рифлекшън нямам почти никакъв опит и от там ми дойде голямото замотаване и не успях да изчистя всички бъгове.

Първо във Views си бях сложила всички видове View в една папка и докато открия грешката голям зор видях. Изтрих част от съставянето на fullPath и стана.(до голяма степен е свързано с това, че не съм вникнала в условито).

Второ като спазвах правилото за пълно наименуване, бях преименувала всички методи в контролерите с доста описателни наименования какво правят. Да ама рифлекшъна не можеше да ги открие и там загубих ужасно много време(над час). Посе видях, че референциите са им 0 и е можело да се сетя, че се викат с рифлекшън, но късно.

Имам въпрос- гледам много хора са с 16 точки. Имахте ли опит с рифлекшън? Или аз съм пропуснала някъде това обучение или просто вие сте чели допълнително. Единствено в една от изпитните задачи по OOP го бях срещала(май беше ConsoleForum).

Не съм доволна от представянето си и ако имам време ще отида на поправката(дано да е скоро).

Bottleneck не мога да открия- дадох Course да имплементира IComparable. Предполагам ми гърми откъм време CoursesController.All.

Писах набързо някаква документация и единствените тестове които успях да генерирам са с Intellitest.

Ето го и решението ми. Добре дошли са коментарите на всеки, който има време да го погледне.

https://github.com/EBojilova/CSharpHQC/tree/master/Exam/230815/MySolution

Тагове:
4
C# OOP Advanced 23/08/2015 21:56:24
WindWallk avatar WindWallk 95 Точки

Изпита беше идеален откъм обем, НО

Мисля, че ако не беше гадния рефлекшън(с който никой от нас не беше запознат) щях да предам много по-добре рефакторирана работа и с добри Unit тестове, а може би и мокинга щях да пробвам...

Аз както и другите оправях неймспейсовете и имената и изгубих сигурно 1 час да оправям бъгове които са супер лесни и то само заради гадния рефлекшън. 

Не съм убеден, че рефлекшъна в случая беше в съответствие с КПК.... Все пак се препоръчва да се използва само когато е наложително, а случая не беше такъв...

Въпроса ми е следния: Този изпит беше за да се научим какжо е рефлекшън и да ни проверят колко бързо можем да разберем как работи нещо с което не сме се сблъсквали до сега или да покажем до колко сме овладяли материала...

И аз, както и други колеги над мен са споменали, не съм убеден, че една лекция и 1 задачка за unit тестовете беше достгатъчна за обяснението им... Има още много материал за тях на който ни оставиха да си го търсим в интернет и да си търсим евентуално от някъде нещо за тестване за упражнение...

За моя радост успях да разбера как работи пустия рефлекшън и да оправя всички бъгове, да рефакторирам колкото време имах, да намеря 1-ния bottleneck и да понапиша unit тестове до колкото успях

Да обобщя: Поредния лош изпит по КПК.... + недостатъчно подготовка(предните изпити не ги броя... те са просто нереални да бъдат направени за 6 часа....)

ПП. Данчо, задачата беше интересна, но този рефлекшън не мисля, че му е там мястото..

4
24/08/2015 17:45:08
KatyaMarincheva avatar KatyaMarincheva 572 Точки

Преди малко във фейсбук страницата ми се появи този линк:

http://www.7financial.com/%D0%B8%D0%BC%D0%B0-%D0%BB%D0%B8-%D1%81%D0%BC%D0%B8%D1%81%D1%8A%D0%BB-%D0%BE%D1%82-%D1%83%D1%87%D0%B5%D0%BD%D0%B5%D1%82%D0%BE/

https://www.facebook.com/svetlin.nakov?fref=nf

и като прочетох идеята за правенето на нещо, което ме вдъхновява - първото нещо, за което си помислих, бяха проектите които Данчо ни беше дал за екипна работа.

От години цялото племе програмисти в семейството ми в един глас обяснява, че трябва да започна работа по open sourse проект, аз разбира се не се решавах дори да си потърся такъв. Работата по екипния проект по КПК е най-вдъхновяващото нещо, което ми се е случвало някога - правих с удоволствие неща които умея и харесвам.

Да, вярно е, че вместо за проекта можех да отделя повече време за учене за изпита, но не съжалявам - на изпита винаги ще се явя за повишение. Проекта си струваше всяка минута, и винаги ще съм благодарна на Данчо за това, че с избора на тези екипни проекти ни въведе в истинското програмиране.

За изпита..... Данчо и на видеото за подготовката, и в указанията за изпита (и Фил също) обясни, че откриването на бъговете не е това, с което се почва, и не е това, което носи основните точки - аз съм си виновна, че 4 часа опитвах да оправям бъгове, и то като заменям всяко registry с речници......, и после почбах отначало и претупах част от основната работа по задачата за 2 часа само, можех с лекота да си направя и mocking - не си оставих време.... Като се явя следващия път ще знам какво да не правя :)

 

 

 

0
Filkolev avatar Filkolev 4482 Точки

Да споделя и аз мнението си за изпита, тъй като все пак го реших, макар и не цялостно (нямах време за документацията и юнит тестовете, а и не бяха приоритетни). Ще дам и малко градивна критика и насоки, защото смятам, че доста от оплакванията, които прочетох, не са много основателни.

Преди да си помислите нещо от рода на "ее, чакай сега, къде е Фил, къде сме ние", имайте предвид, че нашето КПК беше доста слабо, тъй като беше паралелен курс. Важен и тежък предмет винаги се оказваше второстепенен, защото на преден план имахме изпити по нещо друго, най-вече JavaScript. Решавал съм един лаб, който представляваше изпитна задача без тестове (не ги бяхме взели още), един изпит за подготовка и изпитът. И разбира се вашия изпит, който реших в събота. Почти съм сигурен, че по-подготвените хора от вашия випуск имат по-добра подготовка от мен, защото вашата концентрация последните няколко седмици е изцяло върху КПК.

На мен изпитът много ми допадна. Беше преценен като сложност, не беше over-the-top осран (демек беше си четим) и показа MVC архитектурата, което според мен е доста полезно предвид програмата в следващите нива.

Някой по-горе каза, че този изпит бил почти толкова труден колкото Vehicle Park. Горчиво бърка. Докато на този изпит над 15% от хората успяха да вземат максимума точки от джъджа, при нас нямаше нито един. Т.е. бяха ви спестени много неща, които по мнението на мен и колегите ми от моя випуск нямат много общо с КПК-то и не са неща, за които следва да се губи време на изпита. Мненията ни явно са били взети предвид, защото аз прекарах около 3 часа в продуктивно рефакториране, без да ми се налага да трия 10 страници табулации и да уча чужд език. Изобщо доста преценено беше омазан проектът и беше ясно кое какво е. При нас имаше класове и методи, които не можехме да ги разберем какви са преди да пуснем дебъгера. Ако не се лъжа 17 страници условие, в което може да се загубиш и съответно 90% от хората не бяха видели, че на едно място трябва да се сортират някакви неща. На този изпит - кратко условие, всичко важно синтезирано в таблици, с които си направих целия изпит. По-добре разписано условие за изпит трудно може да се изисква.

Относно болната тема - рефлекшъна. На нашия изпит по ООП имаше релфекшън, тогава и идея си нямахме какво е това, така че не сте пионери. В целия проект само в еднжина има рефлекшън и на едно място в контролера ако не се лъжа. Целият енджин е 60 реда. Самият рефлекшън се прави с методи, които са именувани по начин, който ясно подсказва какво се случва. 

 var controllerType = Assembly
                    .GetExecutingAssembly()
                    .GetTypes()
                    .First(type => type.Name == route.ControllerName);

Взимаме асемблито (текущото, това, което рънва в момента), взимаме всички негови типове и хващаме първия, чието име отговаря на някакъв стринг, взет от рута, демек от входа. На този етап от обучението би трябвало да знаете какво е асембли, какво е тип и методите от LINQ.

 var controller = Activator.CreateInstance(controllerType, database, user) as Controller;

Викаме някакъв статичен метод, който, според името му, създава инстанция на нещо. Като първи параметър се подава типа, т.е. какво искаме да създадем, като следващи параметри се подават параметрите, които конструкторът на съответния тип очаква да получи. Методът връща object, затова накрая има кастване с as. Това сте го виждали ако сте гледали нашия изпит по ООП (Console Forum), или уъркшопа, който аз водих преди няколко месеца. Общо взето с това се изчерпва и моят опит с ползването на рефлекшън.

var action = controllerType.GetMethod(route.ActionName);

var view = action.Invoke(controller, parameters) as IView;

Тук влизаме в напълно непознати за мен води. От контролера взимаме някакъв метод с GetMethod и подаваме името на метода като стринг. Получаваме някакъв action, който е MethodInfo. Викаме Invoke с някакви параметри. Е, явно е, че викаме съответния метод, след като сме го взели, и викайки го му подаваме нужните параметри.

В метода MapParameters имаме:

 return action.GetParameters()...

action е метод, GetParameters очевидно ще бръкне в асемблито да вземе параметрите му. Оттам нататък се ползва LINQ, за да се преровят тези параметри и да се провери кои са int.

Основният проблем на повечето хора не е в рефлекшъна, а в неефективното дебъгване. Пример:

var viewType = Assembly
                .GetExecutingAssembly()
                .GetType(fullPath);

return Activator.CreateInstance(viewType, model) as IView;

Взимаме някакъв тип чрез пълния му път (всички неймспейси и накрая името на класа). Разбира се при положение, че пътят е грешен, това ще хвърли грешка. Това се вижда още на първата стъпка, когато viewType излиза null. Е, гледа се пътя, и се проверява дали е правилен. Виждате къде програмата търси съответния клас и къде вие сте го сложили. 

В случая рефлекшъна прави две неща: 

1) Прави приложението по-гъвкаво, защото може без проблем да се добавят безброй много вюта, като ще трябва да се добавят и съответни методи в контролера. Без рефлекшън ще трябва суич в енджина и този суич да се ръчка при всяко добавяне.

2) Принуждава ви да си структурирате приложението правилно. Да има папка Views и в нея подпапки Users и Courses. Дори това да не беше изрично казано в условието (а то дори беше нарисувано), логично е като има около 10 класа в две категории да ги разделите в два отделни неймспейса. Вадите класовете в отделни файлове, слагате ги в правилните неймспейси и рефлекшъна тръгва. Ако държите да слагате View на името на класа - не е проблем, добавяте го като суфикс във fullPath променливата.

Беше казано, че няма забранени неща. Ако бяхте решили, че структурата трябва да е друга, променяте fullPath да отговаря на вашата логика. Можехте дори изцяло да го разкарате рефлекшъна и да теглите един суич. Всичко, което считате, че подобрява качеството на кода.

Относно преименуването на методите - да, кофти. Но това е сигнал за прибързване - правите промени по кода преди да сте разучили как точно работи. Това още от ООП го говорим - първата работа е да разберете приложението преди да пипате по него. Преждевременно рефакториране - във всеки по-голям проект ми се случва, почти винаги в екипните работи; решавам, че нещо трябва да бъде другаде, местя го и всичко се срива. Нормално е за по-неопитни хора и ще се случва редовно ако не се ползват някакви фреймуърци, които го предотвратяват това.

Тъй че рефлекшъна не е фактор в цялата работа. Имаше един по-гаден бъг в MapParameters, който ми отне около 15 минути да го открия, но тук не говорим за опит с рефлекшъна, а за обикновено дебъгване на ламбда функция, демек на foreach. Методът търси параметър courseId, пък в контролера въпросният параметър е сложен само като id -> KeyNotFoundException.

По логистични причини пропуснах голяма част от курса, но от упражненията, които прегледах, ми направи впечатление, че Данчо още от самото начало ви караше да четете чужд код, да се ровите в големи проекти. Не може да знаете всичко и няма как всичко да бъде вкарано в един курс. Нормално е и целенасочено се слагат неща, които не са изучавани. Но правилото е - това, което не е учено, работи. Т.е. очаква се да схванете какво прави да речем Activator.CreateInstance, за да може ако някъде другаде има проблем да знаете защо точно този метод ви гърми. Например, подавате грешни параметри на конструктора. Виждате какъв клас се опитвате да инстанциирате, гледате какво иска конструкторът и виждате къде е несъответствието. Разликата е там, че това нещо ако го объркате ще изгърми runtime, а по принцип ако си викнете конструктора с new и не подадете каквото трябва ще се хвърли грешка още по време на компилация.

Така че, дава се нещо, което не е толкова сложно да се схване, и вашата работа е да си оправите другите части от приложението, за да тръгне. Иска се рефакториране и дебъгване, затова според мен беше доста на място всичко.

Относно MVC архитектурата, някой спомена, че се дебъгва трудно, защото минаваме от 9 класа в 10-ти. Така е, ще става все по-засукано. Чакайте да дойде JS Apps курсът, където ви гърми с "undefined is not a function" или друго подобно "описателно" съобщение от някоя минифицирана библиотека. Големи приложения не се дебъгват лесно ако не ги познавате. В случая е сравнително лесно. Моделите, това са класовете, там си правите валидациите и толкоз. Няма какво да гръмне там ако не сбъркате по невнимание. Вю-тата просто създават съобщенията, единствена грешка там би била правописна/печатна. Т.е. ако програмата ви гръмне с ексепшън, почти със сигурност това се е случило в енджина или контролера, където е реално цялата логика. Или в репозиторитата ако не сте инстанциирали някоя колекция (NullReferenceException). Слагате брейкпойнт където трябва и така няма да се налага да помпате F10 и F11 да минавате през очевидно верни методи. Или натискате F5 и виждате къде гърми. Това трябва да са до болка познати техники. 

Надявам се като ви поотминат страстите, че сме ви забили с неизучавани неща, всеки ще си направи равносметка къде всъщност е сбъркал - в подхода към самия изпит, в избързване с промените, в недобро дебъгване или друго. В крайна сметка КПК е курс, който цели да подготви хората да създават и работят по (т.е. да не засират) големи проекти, а не може в голям проект да има само if-else, for, foreach, StringBuilder и малко LINQ. Ще има много неща, които виждате за пръв път, външни библиотеки и др. За всичко си има документация (това в случай, че кодът не е self-documented, когато и документация не ви е нужна даже). Така че гледайте позитивно на нещата и вземете максимални ползи от неделя.

6
StrahilRuychev avatar StrahilRuychev 117 Точки

Да си кажа и аз мнението за изпита.

Това ми беше третия (и последен!) път, в който се явявам на изпит по КПК :) Редовния ми изпит беше общо известния vehicle park, който ми се стори доста труден - поне за нивото ми тогава. С изпита от оня ден се справих по-добре, отколкото с vehicle park не защото беше по-лесен, а защото не искаше толкова много време да се изгуби за реформатиране на кода (в триене на празни редове, излишни интервали, разцепване на един ред код на няколко реда, преименоване на променливи от бразилски на български, методи и т.н.) При vehicle park 4 часа реформатирах, докато стигна до момента, в който мога да си помисля да търся бъгове и пърформънс ботълнеци.

След три явявания, извода който си направих е, че едно от най-важните умения е това да можеш да дебъгваш добре - да познаваш как работи дебъгера, да си слагаш брейкпойнти, да можеш да влизаш в методи и да излизаш, да си пускаш приложението ред по ред и т.н.

Едно предложение за всички, които смятат да се явяват пак: автоматизирайте си въвеждането на командите от нулевите тестове вместо всеки път да копи-пействате на конзолата. Аз си бях направил един статичен клас, с един статичен List<string> в който всеки елемент беше отделна команда от нулевите тестове (копирана от условието). И направих енджина да взима команди от този статичен клас една по една, вместо от конзолата. Пускъм първата команда, виждам какво изважда, ако е ОК - минавам на следващата. Ако не - дебъгвам. Чак когато ги минах всички (става лесно и бързо) върнах енджина обратно да си чете от конзолата. (Да си призная - този подход не съм го измислил аз. Наков го препоръчва във Въведение в програмирането със C# - да се хардкодне инпута докато тестваш алгоритъма.)

3
EBojilova avatar EBojilova 330 Точки

Фил, както казах и на теб след изпита, аз се издъних и не го отричам. Не започнах с дебъгване и накрая буквално се бях  отказала и бъгнала заради цялата каша с проекта.

Аз решавах почти всички изпитни задачи преди изпита- с изключение на Ticket office, тъй като се дублираше с Travel agency. Решавала съм и Vehicle Park System. Това, че няма достигнати максимален брой точки на вашия изпит съм споделила защо е в темата за изпита ви. Просто не е било възможно- ето какъв е бил проблема с нея- ако е липсвала тази информация в заданието, не знам как някой е успял да не му гърмят последните 3 теста: 

Видовете ексепшъни и съобщенията при валидиране на пропъртита на Vehicle, дадени ли бяха на изпита, тъй като в заданието не ги виждам. По-точно имам в предвид:

throw new ArgumentException("The license plate number is invalid.");

throw new ArgumentException("The owner is required.");

throw new ArgumentException(string.Format("The {0} rate must be non-negative.", name)); name is regular/overtime

throw new ArgumentException("The reserved hours must be positive.");

Оказа се, че тъй като си бях въвела мои съобщения на ексепшъните ми гърмят последните 3 теста, тъй като искат точно гореспоменатите съобщения. А не ги виждам в условиeто(или гледам старо условие?).

Това ти го давам като пример, че достигнати максимален брой точки на изпита не говори за това кой изпит е бил по-труден.

Като човек решавал и двете задачи, то тази от изпита на 23.08.15 на мен ми се видя по-трудна. Вашия изпит го реформатирах автоматично с Clean Up прозореца и ReplaceAll за Entire Solution, като спазвах да се зачита кейсинга и цялоста на думата и самото реформатиране ми отне много малко време(имам и Стайлкоп и решарпер, които са интегрирани и става много бързо). На една от задачите, не помня коя, само премахнах празните редове пак автоматично и Clean Up прозореца започна да действа(тъй като преди това не действаше). На вашата задача, както споменах беше друг проблема. На Vehicle Park System загубих над 5 часа да се пробвам сама да открия защо ми гърмят последните 3 теста и това ми беше проблема. Така, че мненията ни се различават относно трудноста на двата изпита определено.

Дебъгвам непрекъснато и доста добре се справям, дори с различните видове break point. Но ако всичко в програмата ти гърми, бая breakpoint- и трябва да сложиш. След като се светнах как работи рефлекшъна, реших задачата за нула време. Сещам се и че на една лекция показа къде да погледнем лекция на Данчо за рефлекшъна, но не стигнах до там.

Благодаря ти за отзивчивоста, и времето, което намираш за нас във форума. По ООП се справих доста добре, точно заради видеата, които беше пуснал.

2
26/08/2015 14:21:45
EBojilova avatar EBojilova 330 Точки

Подготвям се в момента за поправката. Реших да погледна юнит тестовете на авторското решение, тъй като те ми куцат по принцип. В авторското решение, обаче няма тестове. Може ли да качите и тестовете към него?

0
18/10/2015 10:25:24
malkstor avatar malkstor 348 Точки

Здрасти Елена :)

Тук са тестовете за този изпит, а тук са всички КПК курсове.

ПП. Сега като гледам коментара на Фил - да, съгласен съм. От друга страна и като вече имам идея как работи reflection-а, изпита не е сложен. Ще видим в сряда дали ще има

3
EBojilova avatar EBojilova 330 Точки

Здрасти, Асене,

Имах предвид Unit Tests.

:)

0
18/10/2015 21:33:43
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.