Практические задания по курсу "Язык CSharp и платформа .NET" — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Задание 6а на регулярные выражения)
(Задание 6а на регулярные выражения)
Строка 215: Строка 215:
  
 
г) Вывести все строки, начинающиеся с пробела
 
г) Вывести все строки, начинающиеся с пробела
 +
 +
д) Вывести номера символов, с которых начинается каждая строка
 +
 +
е) Вывести все URL в файле в формате http://edu.mmcs.sfedu.ru/ (последний слеш необязателен) и места их вхождений (строка-столбец). Номер столбца подсчитывать, используя результат предыдущего задания (находить номер, с которого начинается строка, в которой нашли вхождение, после чего находить индекс вхождения в этой строке)
  
 
====Задание 7 на контейнерные классы====
 
====Задание 7 на контейнерные классы====

Версия 09:33, 2 апреля 2012

Практические задания по курсу "Язык C# и платформа .NET"

Задание 1 (начало)

1.1. Откомпилировать простейшую библиотеку .dll и простейшую программу .exe, вызывающую методы библиотеки, с помощью csc.exe. Записать размер полученных файлов.

1.2. Просмотреть метаданные в сборках .dll и .exe с помощью ILDasm

1.2a. Создать простейшее оконное приложение и записать его размер.

1.3. Написать аналогичную dll на PascalABC.NET, просмотреть метаданные с помощью ildasm и вызвать метод dll в программе на C#

1.4. Вызвать метод из dll, написанной на C#, в программе на PascalABC.NET

Задание 1а

1.5. Откомпилировать сборки exe и dll с помощью Visual Studio в режимах Debug и Release. Сравнить размеры полученных файлов.

1.6. Аналогично обеспечить межъязыковое взаимодействие VB.NET <--> Managed C++

Задание 1б

1.7. Сравнить скорость работы вычислительного алгоритма на языках C#, C++, Java, PascalABC.NET, Free Pascal

a) <math>\sum_{i,j\le n}\frac{1}{i*j} </math>, n - достаточно большое
б) <math>\sum_{i,j\le n}\frac{1}{a_i*a_j}</math>, n - достаточно большое

В случае б) заполнить массив a случайными числами в диапазоне от 1 до 1.1

Сравнивать скорость в Debug и Release - конфигурациях (для FP включать все возможные оптимизации).

Для .NET-языков сравнить IL-код для циклов с помощью ildasm и выявить неэффективность генерации кода.

Задание 1в

1.8. Создать сборку, содержащую статический класс MyArray со статическими функциями, реализующими алгоритмы работы с одномерными и двумерными массивами произвольного типа T. Функции должны описываться в виде

static type Name<T>(T[] arr, anotherparams)

Для одномерных массивов:

FillRandom
Print
Insert
Delete
CycleShiftLeft
CycleShiftRight
Concat - конкатенация двух массивов в один
Find - поиск

Для двумерных массивов:

FillRandom
Print
Transpose
DeleteRow
DeleteCol
Find - поиск
Submatrix - вырезание подматрицы

Написать программу, тестирующую все указанные функции.

Замечание 1. Для заполнения случайными числами воспользоваться классом Random.

Замечание 2. Поскольку некоторые функции меняют размеры массива, рекомендуется вторым параметром для массива передавать по ссылке его текущее количество элементов, например:

static void Insert<T>(T[] arr, ref int len, T x)

Замечание 3. Для одномерных массивов доступно на чтение свойство a.Length. Для двумерных массивов для создания и использования:

int [,] a = new int[5,6];
a.GetLength(0);
a.GetLength(1);
a.Rank

Задание 2 на наследование и полиморфизм

2.1. Создать иерархию классов Person-Student-Teacher. Каждый класс – в своей сборке. В каждом классе должны быть свойства, а также виртуальная функция Print и переопределенная функция ToString(). Основная программа создает массив объектов Person или их наследников, после чего выдает его на экран. У каждого Teacher должен быть список Students, которыми он руководит, у каждого Student - Teacher, который им руководит.

Замечание. В процессе реализации возникнет такая ошибка как циклическая зависимость сборок: сборка Student зависит от сборки Teacher и наоборот. Для устранения этой ошибки рекомендуется создать класс Student без поля Teacher, после чего создать производный класс StudentWithAdvisor с полем Teacher в отдельной сборке.

2.2. Для классов Person-Student-Teacher реализовать ToString(), Equals(), GetHashCode().

2.2а. С помощью is, as, GetType определить, сколько в массиве персон, студентов и преподавателей и перевести всех студентов на следующий курс.

2.3. Для классов Person-Student-Teacher реализовать глубокое клонирование, определив виртуальный метод Clone(). Клон должен возвращать точную копию по значению и типу. Проиллюстрировать Clone на примере контейнера персон.

2.4. Используя метод GetType() класса Student и метод BaseType() класса Type, вывести всех предков класса Student (написать общий метод)

2.5. (не нужно) Проиллюстрировать использование полиморфизма для модификации некоторого кода в будущем. Виртуальные методы должны выполнять роль сменных блоков, действие которых будет в будущем переопределено.

Замечание 1. Свойства ("умные" поля) определяются так:

public int age;
public int Age {
  get { return age; }
  set { if (value<0) value = 0; age = value; }
}

Здесь value - переменная, неявно объявленная в каждом сеттере. Свойства отличаются от полей тем, что при доступе на чтение и запись можно совершать дополнительные действия. Обычная практика - проверка в сеттере значения на допустимость и его исправление или генерация исключения.

Замечание 2. В конструкторе потомка следует вызывать конструктор предка в списке инициализации:

Student(...): base(...) {}

Замечание 3. Виртуальные функции следует объявлять с ключевым словом virtual в предке и с ключевым словом override в потомках. Виртуальную функцию следует вызывать через переменную базового класса:

Person p = new Student(...);
p.Print();

Замечание 4. Функции ToString() и Equals() определены в базовом классе Object как виртуальные.

Замечание 5. p is Student возвращает True если в p - студент или производный класс. p as Student преобразует тип p к Student, а если это невозможно, возвращает null.

Замечание 6. Для сравнения на точное совпадение типа используется GetType: if (p.GetType()==typeof(Student))

Задание 3 на перегрузку операторов

3.0. Для классов Person-Student-Teacher реализовать ==, !=

3.1. Создать структуру Complex с перегруженными операциями, а также с возможностью приведения типа double->complex. Должны быть реализованы также ToString(), Equals(), ==, !=

3.2. Создать класс Frac с перегруженными операциями + - * / , а также с возможностью приведения типа Frac->double. Должны быть реализованы также ToString(), Equals(), ==, !=. Вычислить значение полинома в точке. Все коэффициенты и x должны иметь тип Frac.

Замечание 1. Операции реализуются как статические методы:

 public static bool operator==(Person p1, Person p2) {return p1.Equals(p2);}

Замечание 2. Операции приведения типа определяются так:

public static explicit operator double(Frac f) {...}

explicit означает явное приведение типа, вместо него может стоять implicit - неявное приведение типа.

Задание 4 на индексаторы

4.1. Создать класс, реализующий битовый массив на основе обычного, используя индексные свойства.

  • 4.2. Создать класс RGB, реализующий индексное свойство, возвращающее по строке с именем цвета цвет System.Drawing.Color.

4.3. Создать класс ассоциативного массива, используя два списка.

Задание 5 на строки

5.1. (не надо) Проверить механизм интернирования строк

5.2. Дана строка слов. Убрать лишние пробелы и упорядочить слова по алфавиту. Воспользоваться методом расщепления s.Split(массив разделителей,System.StringSplitOptions.RemoveEmptyEntries) строки на массив строк и методом string.Join(разделитель,ss) слияния массива строк в строку. Аналогично упорядочить слова по длине, записав их в единой строке.

5.3. Вводятся вещественные числа (возможно, на нескольких строках), конец ввода - 0. На одной строке может быть несколько вещественных чисел, а также не числа. Используя метод Append класса StringBuilder, сформировать строку, в которой эти вещественные числа разделены одним пробелом, и количество цифр в дробной части равно 1. Не числа - игнорировать. Для разбора вещественного использовать double.TryParse, для форматирования вещественного - d.ToString (формат вывода для вещественного с 1 цифрой в дробной части)

5.4. Используя тот факт, что для объекта StringBuilder доступна операция обращения по индексу [] на запись, преобразовать в строке слов первую букву каждого слова в заглавную.

5.5. Используя различные кодировки System.Text.Encoding, преобразовать строку "Спецкурс C# и платформа .NET 2012" в массив байтов. Для этого использовать GetBytes соответствующей кодировки:

System.Text.Encoding.UTF8.GetBytes(s); 

Для того чтобы получить список всех поддерживаемых кодировок, воспользуйтесь методом

Encoding.GetEncodings();

возвращающим массив объектов EncodingInfo.

5.6. Используя System.Globalization.NumberFormatInfo, переопределить разделитель в вещественном числе с запятой на точку (в русских версях windows по умолчанию - запятая). Для этого создать экземпляр NumberFormatInfo и переопределить в нем свойство NumberDecimalSeparator на '.'. Для преобразования вещественного в строку воспользоваться d.ToString(nfi), где nfi - переменная типа NumberFormatInfo. Для считывания вещественного с другим разделителем воспользоваться преобразованием строки в вещественное

double.Parse(s,nfi);

Реализовать на основе этого суммирование всех вещественных, записанных в строке в виде

 3.14    2.8   4.19  5.3

и вывести результат в виде

3.14 + 2.8 + 4.19 + 5.3 = ...

5.7. Используя объект System.Globalization.DateTimeFormatInfo, переопределить свойство DateSeparator на ';'. Проверить работу нового формата, выведя текущую дату DateTime.Now в новом формате. Используя указанный формат, считать строку, содержащую две даты в указанном формате и найти дни недели, соответствующие этим датам, а также разницу между этими датами в днях, часах и минутах.

5.8. Считать содержащиеся в строке шестнадцатеричные числа

 AAFF    BCDF     1FF4    123D9     CC11D3

и просуммировать их. Результат выдать в восьмеричной системе счисления.

Задание 6 на интерфейсы

6.1. Проверить, как работает явная и неявная реализация методов интерфейса.

6.2. В классе Student реализовать интерфейс IComparable<Student>. Воспользовавшись Array.Sort, отсортировать массив студентов.

6.3. Реализовать интерфейс IComparer<Student> в классе StudentComparer, вложенном в Student. Параметром его конструктора должен выступать критерий сортировки. Воспользовавшись второй формой Array.Sort, отсортировать массив студентов по разным критериям.

6.4. Реализовать в классах Person-Student-Teacher интерфейс ICloneable и проиллюстрировать его использование.

6.5. Реализовать интерфейс IDisposable и убедиться в корректности его работы в операторе using

Интерфейс IDisposable имеет вид:

interface IDisposable {
  void Dispose();
}

Он используется для детерминированного освобождения ресурсов в стиле C++, метод Dispose играет роль деструктора. Если класс My поддерживает интерфейс IDisposable, то его можно использовать в операторе using:

using (My m = new My())
{

} // в конце гарантированно вызовется Dispose

6.6. Создать контейнер Students, который можно было бы использовать в foreach. Реализовать интерфейс IEnumerator<Student> двумя способами: самим классом Students и вложенным приватным классом StudentsEnumerator.

Задание 6а на регулярные выражения

Теория по регулярным выражениям (Абрамян М.Э.)

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

6a1. Вывести все слова - каждое на отдельной строке

6a2. Вывести все слова, начинающиеся и заканчивающиеся на 'a'

6a3. Вывести все слова, содержащие в начале от 2 до 4 согласных букв

6a4. Вывести все числа с десятичной точкой и вычислить их сумму

6a5. Вывести все полные имена файлов (и только их). Полные имена файлов задаются в формате Диск:\папка1\папка2\имя.расширение. Диск и папки могут отсутствовать.

6a6. Вывести все URL в строке в формате http://edu.mmcs.sfedu.ru/course/view.php?id=9.

6a6. Считать многострочную строку из файла слов (слова могут разделяться одним или несколькими пробелами и символами перехода на новую строку), используя вызов

var s = System.IO.File.ReadAllText('Text.txt');

Создать регулярное выражение с опцией RegexOptions.Multiline.

а) Вывести все слова, стоящие в начале строки.

б) Вывести все слова, стоящие в конце строки.

в) Вывести все слова, стоящие первыми в строке (перед словами могут быть один или несколько пробелов)

г) Вывести все строки, начинающиеся с пробела

д) Вывести номера символов, с которых начинается каждая строка

е) Вывести все URL в файле в формате http://edu.mmcs.sfedu.ru/ (последний слеш необязателен) и места их вхождений (строка-столбец). Номер столбца подсчитывать, используя результат предыдущего задания (находить номер, с которого начинается строка, в которой нашли вхождение, после чего находить индекс вхождения в этой строке)

Задание 7 на контейнерные классы

7.1. Сравнить производительность ArrayList и List<int>

7.2. Для словаря, состоящего из пар (строка, число), сравнить производительность HashTable, SortedList, SortedDictionary<K,T>, Dictionary<K,T> на больших объемах данных.

7.3. Дан файл слов. Создать частотный словарь слов, используя SortedDictionary<K,T>. Вывести слова, упорядоченные по алфавиту и по повторяемости.

Задание 7а на методы расширения

7.4. Разработать метод расширения для IEnumerable<T> - вывод на экран, разделяя разделителем, переданным в качестве параметра.

7.5. Разработать методы расширения для IEnumerable<T> - сдвиг влево на k, сдвиг вправо на k

7.6. Разработать метод расширения для IEnumerable<T>, записывающий значения, удовлетворяющие предикату, в один IEnumerable<T>, а не удовлетворяющие - в другой, и возвращающий пару указанных IEnumerable<T>.

7.7. Разработать метод расширения для IEnumerable<T>, применяющий функцию Func<T,T1>(T t) к каждому элементу и возвращающий IEnumerable<T>

7.8. Разработать метод расширения для IEnumerable<int>, переставляющий элементы на четных и нечетных местах.

Задание 8 на LINQ

Даны коллекции студентов, кафедр, предметов, и коллекция, задающая связь (Idпредмета, Idстудента, дата записи на курс)

8.1. Вывести 10 первых студентов с максимальным рейтингом

8.2. Вывести количество различающихся рейтингов студентов

8.3. Вывести все предметы, которые посещает данный студент

8.4. Вывести всех студентов, сгруппированных по кафедрам

8.5. Вывести всех студентов, сгруппированных по среднему баллу: от 5 до 4.5, от 4.5 до 4, от 4 до 3 и все остальные

  • 8.6. Вывести все пары (студент,курс). Реализовать подзапрос

Задание 9 на файлы и потоки

9.1. В текстовом файле записаны вещественные числа (на каждой строчке - несколько, разделены несколькими пробелами) и что-то ещё. Найти сумму чисел, игнорируя неверные лексемы.

9.2. Создать типизированный файл целых, затем модифицировать его, возведя все элементы в квадрат.

9.3. Для данной директории рекурсивно выдать список её файлов и поддиректорий.

F#. Основы

Язык F#. Основы

  1. Найти НОД(a,b)
  2. Найти сумму квадратов чисел от 1 до n
  3. Найти сумму и произведение цифр целого числа
  4. Установить, является ли число простым
  5. Разложить на простые числа
  6. Найти 1!+2!+3!+...+n!

Язык F#. Списки, кортежи, записи

F#. Списки

Не пользуясь стандартными функциями, реализовать следующие операции для работы со списками:

  1. Найти сумму элементов списка >5
  2. Написать функцию, определяющую, есть ли данный элемент в списке
  3. Написать функцию, определяющую, удовлетворяется ли условие cond для всех элементов списка
  4. Слить 2 списка в один
  5. Выделить n-тый элемент списка
  6. Определить длину списка
  7. Выделить последний элемент списка
  8. Вернуть список без последнего элемента
  9. Инвертировать список
  10. Найти минимальный элемент списка
  11. Найти индекс элемента списка, удовлетворяющего условию cond
  12. Найти СКАЛПР двух списков
  13. Упорядочен ли список по возрастанию

Задание 10 на сериализацию

  • 10.1. Используя BinaryFormatter и атрибут [Serializable], сериализовать на диск в бинарном формате объекты классов Student и Teacher, после чего десериализовать. Добавить в Student список оценок List<int> и ссылку на преподавателя Teacher. Убедиться, что сериализация работает корректно.
  • 10.2. Используя DataContractSerializer, его методы ReadObject и WriteObject и атрибуты [DataContract] для класса и [DataMember] для открытых полей или свойств, сериализовать на диск в XML-формате объекты класса Student. Вызвав конструктор DataContractSerializer в виде new DataContractSerializer (typeof (Student), new Type[ ]{typeof (SeniorStudent)}), сериализовать-десериализовать также потомков Student типа SeniorStudent.
  • 10.3. Используя класс XMLSerializer, сериализовать-десериализовать объекты класса Student в XML-формате. Понять ограничения этого сериализатора.

Задание 11 на события

  • 11.1. Реализовать механизм обмена сообщениями. В программе должна быть организована "переписка" между как минимум тремя объектами как минимум двух различных классов. Количество типов событий - также не менее трех.

Задание 12 на рефлексию

  • 12.1. Используя механизм отражения, "расшифровать" все классы, содержащиеся в dll. Создать объект класса, вызвать его метод, свойство (на чтение и запись).
  • 12.2. Для данного типа вывести цепочку всех его предков и интерфейсов, ими реализуемых.
  • 12.3. Создать программу автоподключения плагинов к программе. Плагин представляет собой dll, содержащую класс, удовлетворяющий некоторому интерфейсу. Программа должна анализировать все классы в dll, отбирать те, которые реализуют интерфейс, создавать по одному объекту каждого такого класса и вызывать методы интерфейса для этого объекта.

Задание 13 на потоки (Threads)

13.1. Создать несколько потоков, выводящих на консоль в цикле свой hashcode. Посмотреть порядок вывода. Добавить Sleep(1), Sleep(10), Sleep(0). Посмотреть изменения в порядке вывода. Закоментировать Sleep() и установить приоритеты потокам. Посмотреть изменения в порядке вывода.

13.2. Написать программу, демонстрирующую работу Join(): основной поток должен дожидаться окончания работы (не менее) 2-х потоков, потом продолжать работу. Конструктивно: дополнительные потоки должны предоставлять данные, необходимые для дальнейшей работы основного потока.

  • 13.3. Продемонстрировать работу критических секций на примере банкомата.

13.4. Используя критические секции, реализовать потокобезопасный класс Стек. Операции Push и Pop должны блокироваться одним объектом. Проиллюстрировать корректность работы стека, выполняя операции Push и Pop случайным образом в разных потоках. Продемонстрировать, что обычный класс стека не является потокобезопасным.

13.5. Продемонстрировать ситуацию с возникновением DeadLock.

  • 13.6. Продемонстрировать работу Monitor'ов (Monitor.Wait, Monitor.Pulse, Monitor.PulseAll). Продемонстрировать отличия Monitor.Pulse и Monitor.PulseAll. Проверить работу Monitor.Wait, Monitor.Pulse для работы с очередью посетителей (один поток генерирует клиентов через разные промежутки времени, второй их обслуживает)

Задание 14 на асинхронное программирование

14.1. Продемонстрировать асинхронную работу методов с использованием пула потоков. Операции для пула потоков должны быть достаточно длительными.

14.2а) Продемонстрировать работу именованного семафора для синхронизации действий между несколькими процессами.

14.2б) Продемонстрировать работу именованного мьютекса для синхронизации действий между несколькими процессами.

  • 14.2в) Продемонстрировать работу ManualResetEvent в ситуации когда несколько потоков дожидаются возникновения события.

14.3. Продемонстрировать выполнение асинхронных вычислительных операций с использованием методов BeginInvoke и EndInvoke для делегатов.

  • 14.4. Продемонстрировать выполнение асинхронных операций ввода-вывода для задачи чтения из большого файла, используя:
  •  :а) модель ожидания
  •  :б) модель опроса
  •  :в) модель с обратным вызовом