Советы и примеры задач, которые помогут вам в освоении нового языка программирования
19 июня 2013
Недавно мне пришло очередное письмо от одного из читателей блога. Автор письма сетовал, что на кафедре, на которой он учится, мало внимания уделяется программированию, а также интересовался, не знаю ли я каких-нибудь приемов, способствующих изучению нового языка программирования. Вот, что я думаю по этом поводу.
Все языки программирования изучаются одинаково. Сначала вы осознаете, что хотите освоить новый язык. Мотивы могут быть самыми разными. Возможно, вы решили начать карьеру программиста, возможно — просто хотите решить своими силами некоторую задачу, а может быть, вы уже знаете десяток языков программирования и учите еще один в надежде открыть в процессе изучения нечто новое и интересное для себя. В любом случае, вы выбираете подходящий для ваших целей язык. Вопрос выбора языка программирования был более подробно освящен в заметке Итак, вы решили стать программистом.
Нынче можно найти массу обучающих материалов на любой вкус — статей в журналах, постов в блогах, видео-курсов и так далее. Встречаются даже интерактивные сайты-учебники. Однако я глубоко убежден, что нет лучшего способа начать изучение нового языка программирования, чем прочитать хорошую книгу по нему. Статьи и видео-курсы оставляют пробелы в знаниях. С их помощью вы можете легко выучить синтаксис языка программирования, но они не дадут вам глубокого понимания его внутреннего устройства. Если в языке используется автоматическая сборка мусора, то как она работает? Если процессы «общаются» при помощи обмена сообщений, каковы гарантии на доставку этих сообщений?
Хорошую книгу в том или ином виде (бумажном или электронном, на русском языке или на английском) можно найти по любому языку программирования. Книги есть даже по недавно появившимся языкам, таким, как Go или Perl 6. Если книг нет, то, скорее всего, язык не заслуживает вашего внимания. Он либо безнадежно устарел, либо появился буквально вчера и, возможно, перестанет существовать уже завтра.
Следует отметить опасность книг на русском языке, особенно переводных. В этих книгах нередко содержаться серьезные ошибки и предпринимаются попытки изобрести собственную терминологию. Если перед вами стоит выбор — прочитать книгу на английском языке или ее перевод на русский, настоятельно советую выбрать первый вариант. Еще одна опасность может подстерегать вас при изучении молодых языков программирования. Например, Scala является новым и очень быстро развивающимся языком. Книги о Scala, написанные буквально год или два назад, уже успели устареть.
Помимо книги по самому языку программирования вам, скорее всего, также понадобится несколько книг по связанным с этим языком технологиям. При изучении Python вы, вероятно, также будете заинтересованы в освоении Django. Если вы изучаете Scala, не повредить прочитать книги по Akka, Play Framework и Scalatra.
Но одних только книг недостаточно. Вряд ли после прочтения книги вы смогли полностью, во всех деталях, запомнить ее содержание. К тому же, в книгах часто не обсуждаются многие важные вопросы. И хотя ответы на них содержатся в официальной документации и тех самых постах в блогах, вы, опять таки, не можете просто прочитать и запомнить их. Настоящее понимание приходит только с опытом. Чтобы по-настоящему освоить язык программирования, нужно много писать на нем, а также читать код других программистов.
Приобретению опыта использования языка способствует решение с его помощью задач. В некоторых книгах в конце каждой главы приводятся небольшие задачки. Но я лично никогда не любил эти задания из-за их искусственности. Мне больше нравится заниматься более-менее реальной задачей и, если потребуется, использовать в ней dict’ы, чем писать пять строк кода, которые делают с этими dict’ами что-то надуманное и никому ненужное. Рассмотрим некоторые из таких более-менее реальных задач (или «коанов», если хотите), сгруппированных по тематике.
Веб:
- Возьмите один из веб-фреймворков для изучаемого вами языка и напишите сайт, который выводит на главной странице надпись «Привет, мир!». В случае с Haskell, к примеру, таким фреймворком будет Yesod, Scotty, Happstack или Snap.
- Добавьте форму для ввода имени пользователя, после отправки которой появляется надпись «Привет, (имя пользователя)!».
- Добавьте сохранение информации о пользователе в кукисах, чтобы посетителю не приходилось каждый раз вводить свое имя при заходе на сайт. Сделайте кнопку «выход», при нажатии на которую кукисы удаляются.
- Дайте пользователям возможность заливать аватарки.
- Пусть у пользователей будет возможность выбирать язык интерфейса.
- Одним пользователям нравится читать черный текст на белом фоне, а другим — белый текст на черном фоне. Дайте им возможность переключаться между несколькими шаблонами сайта.
- Разверните написанное вами приложение в Амазоне или в ином облачном хостинге.
Базы данных:
- Напишите телефонную книгу с использованием какой-нибудь реляционной СУБД, например, SQLite, MySQL или PostgreSQL. Телефонная книга — это приложение, которое хранит информацию о ваших знакомых и способах, которыми можно связаться с ними. Вы можете создавать, редактировать и удалять людей, а также различные их контакты — телефоны, скайпы, адреса блогов и так далее.
- Существуют ли ORM для изучаемого вами языка программирования? Сделайте так, чтобы приложение из предыдущего пункта могло работать с любыми двумя РСУБД, используя один и тот же код.
- Напишите телефонную книгу, используя для хранения информации одну из NoSQL баз данных, например, MongoDB, Couchbase, Cassandra или Riak.
- Напишите небольшое веб-приложение, отображающее число пользователей, находящихся в данный момент онлайн. Для этого воспользуйтесь одним их key-value хранилищ, например, Memcached или Redis. Считается, что пользователь находится онлайн, если он запрашивал одну из страниц сайта в течение последних пяти минут.
Сети и протоколы:
- Напишите программу, выводящую последние 10 твитов, содержащих указанный хэштэг. Используйте HTTP API социальной сети Twitter.
- Напишите агрегатор блогов. Имеется список RSS- и Atom-лент. Программа должна генерировать файл index.html, содержащий ссылки на последние 50 постов, опубликованных в блогах из списка. Настройте автоматический запуск программы каждые 10 минут. Убедитесь, что файл index.html обновляется.
- Добавьте в программу из предыдущего пункта возможность заливать index.html в указанный каталог на удаленном сервере по протоколу FTP. Используйте готовую библиотеку для работы с FTP.
- Напишите программу, отправляющую электронное письмо на указанный адрес по протоколу SMTP с использованием готовой библиотеки. Затем прикрепите к письму несколько файлов. Сделайте так, чтобы в почтовых клиентах с поддержкой HTML отображалась HTML-версия письма с картинкой, а в клиентах без поддержки HTML — простая текстовая версия письма.
- Напишите программу, уведомляющую пользователя о получении новых писем. Используйте протокол POP3. Затем добавьте в программу поддержку IMAP. Убедитесь, что программа поддерживает SSL. Для работы с POP3 и IMAP используйте готовые библиотеки.
- Напишите простого ICQ-, IRC- или Jabber-бота с использованием готовой библиотеки для работы по выбранному протоколу.
- Выберите протокол из следующего списка: DNS, FTP, POP3, SMTP, IRC, IMAP, Jabber, ICQ, ed2k, BitTorrent. Напишите собственную библиотеку для работы по выбранному протоколу со стороны клиента. Или напишите сервер.
- Существуют ли для изучаемого вам языка программирования биндинги к libpcap? Если да, попробуйте написать простой HTTP-сниффер. Если нет, попробуйте написать простой аналог libpcap на raw-сокетах.
Многопоточность:
- Напишите программу, которая в несколько потоков скачивает файлы по заданному списку URL-адресов. Используйте «традиционную» многопоточность с мьютексами, семафорами и так далее. Разумеется, если она поддерживается изучаемым вами языком.
- Решите ту же задачу с использованием процессов операционной системы вместо потоков.
- Можно ли в изучаемом вами языке использовать легковесные потоки, событийно-ориентированное программирование или транзакционную память? Попробуйте решить задачу с помощью одного из этих подходов.
Графика:
- Напишите программу, рисующую диаграммы для некоторых данных. Программа должна уметь строить графики, гистограммы и круговые диаграммы.
- Задан список пар однонаправленно связанных элементов. Напишите программу, отображающую эти данные в виде графа.
- Напишите простую библиотеку для рисования Captcha. Используйте GD или аналогичную библиотеку на ваш выбор.
- Напишите конвертер из одного графического формата в другой. Как минимум, программа должна поддерживать форматы bmp, jpeg, gif и png.
Некоторые алгоритмы:
- Напишите программу, собирающую статистику поисковых запросов, по которым пользователи заходят на некоторый сайт. Для этого пропарсите при помощи регулярных выражений логи веб-сервера за месяц.
- Напишите библиотеку для поиска на графах в глубину и в ширину, а также при помощи алгоритма A*. Реализуйте прямой, обратный и двунаправленный поиск.
- Напишите генератор лабиринтов. Затем напишите программу, которая проходит лабиринты, сгенерированные предыдущей программой.
- Найдите сайт, использующий как можно более простую Captcha. Напишите программу, распознающую символы на этой Captcha. Используйте многослойные нейронные сети.
- Аппроксимируйте функцию синус на отрезке [0; pi/2] при помощи полинома четвертой степени. Для подбора коэффициентов воспользуйтесь генетическим алгоритмом. Повторите задачу для другой функции и другого отрезка.
- Создайте библиотеку, реализующую алгоритм сжатия LZW. Затем протестируйте библиотеку на типичных данных. Насколько ее скорость и коэффициент сжатия отличаются от этих же параметров у других библиотек для сжатия данных без потерь?
- Реализуйте алгоритм перевода римских цифр в арабские, а также алгоритм преобразования в обратную сторону.
- Напишите библиотеку для работы с графами, матрицами, датами, комплексными числами или числами произвольной длины.
- Напишите свою реализацию хэш-таблиц, RB-деревьев, двусвязных списков, а также других структур данных на ваш выбор.
- Придумайте простой язык программирования и напишите его компилятор или интерпретатор.
Криптография:
- Найдите библиотеку для генерации криптостойких псевдослучайных чисел. Напишите на ее основе генератор паролей. Если такой библиотеки для изучаемого вами языка нет, напишите ее. Из литературы тут можно посоветовать Практическую Криптографию.
- Напишите программу, считающую MD5, SHA1, SHA256 или иную хэш-функцию от заданной строки. Напишите программу, считающую ту же хэш-функцию от большого файла на диске.
- Напишите программу, шифрующую файлы при помощи AES или иного симметричного шифра.
- Найдите библиотеку, реализующую алгоритм RSA. Напишите с ее помощью программу для обмена ключами по открытому каналу (например, электронной почте) и передачи по этому же каналу зашифрованных и защищенных цифровой подписью сообщений.
- Сделайте то же самое с использованием эллиптических кривых. Если для изучаемого языка нет готовой библиотеки для работы с эллиптическими кривыми, напишите ее.
Десктоп:
- Напишите простое GUI-приложение с полем для ввода имени и кнопкой с надписью «ОК». При нажатии на кнопку должно появляться сообщение «Привет, (введенное имя)!». Продолжите работу над приложением. Пусть у программы будет иконка в трее и она будет уметь сворачиваться в этот трей. Научитесь выводить popup-сообщения.
- Можно ли на изучаемом вами языке программирования сделать скриншот экрана и сохранить его в bmp-файл? Если да, то попробуйте написать программу, делающую это.
- Напишите проигрыватель mp3-, ogg- и wav-файлов.
- Создайте программу, которая рисует вращающийся куб с разноцветными гранями при помощи OpenGL или DirectX.
- Напишите приложение, снимающую вебкамерой фото и/или видео.
- Научитесь сканировать документы и отправлять их на печать.
- Напишите программу, записывающую звук с микрофона в wav-файл.
- Напишите генератор Excel-отчетов с графиками и гистограммами. Проверьте, что он нормально отображается в Microsoft Office, Libre Office и Google Docs.
Прочее:
- Выполните любое задание из предыдущих пунктов. Убедитесь, что написанная программа работает как минимум под двумя операционными системами, например, под Windows и под Linux или под Linux и MacOS.
- Напишите программу для рекурсивного поиска файлов на диске. Напишите менеджер процессов. Если вы пишите под Windows, напишите программу, добавляющую себя на автозапуск путем редактирования реестра. Напишите программу, перечисляющую заголовки всех открытых окон.
- Попробуйте написать простую динамическую библиотеку. Затем напишите программу, подгружающую эту библиотеку и вызывающую функции из нее.
- Как вызывать из изучаемого вами языка функции, написанные на Си? Можно ли написать программу на Си, вызывающую функции, написанные на изучаемом вами языке? Если вы изучаете Си, замените в предыдущих двух предложениях «Си» на «OCaml».
- Можно ли писать на изучаемом вами языке под Android, iOS или Windows Phone? Попробуйте написать простое мобильное приложение.
Ух! Немало получилось, правда? Как, все еще мало? В таком случае можно посоветовать следующее. Читайте книги о программировании. Во время чтения придумывается много интересных задачек. Принимайте участие в конкурсах по программированию. Подумайте, какие рутинные задачи вам приходится время от времени решать и попробуйте написать программу для их решения. Участвуйте в open source проектах. Читайте блоги. Полистайте архивы блогов, на которые вы подписаны. В них можно найти интересные задачки. Заведите собственный блог и пишите о ваших успехах в изучении нового языка. Комментарии к постам нередко наводят на интересные мысли.
Ну и в заключение отмечу, что в освоении языка неплохо так помогает найти работу программистом на этом самом языке. Задачи появятся сами собой, а вместе с работой над ними приходит и опыт.
Метки: Языки программирования.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.