Советы студентам-программистам
Привет, Хабр! Представляю вашему вниманию перевод статьи "Advice for programming students".
Есть много вещей, которые я хотел бы знать, когда я начал свое путешествие в качестве студента-программиста. С тех пор прошло почти 10 лет, и, к сожалению, я не могу поделиться своим опытом и знаниями с моим прошлым «я», только с моими младшими коллегами. Этот пост состоит из некоторых полезных советов, которые я хотел бы услышать, когда мне было 18 лет.
Решите, что вам нужно
Вам, конечно, не нужно быть знакомым с формальной логикой или категориями, если вы хотите просто узнать как создать что-то практическое (скажем, интерфейс) и делать только это. Существует два основных пути, которые отличаются усилиями, продолжительностью и исходом.
- Вы можете быстро овладеть одной областью — скажем за один-два года. Вы не будете бесполезны, вы будете делать что-то и зарабатывать на жизнь. Есть достаточно возможностей для трудоустройства (по крайней мере, на данный момент), которые не требуют большой гибкости.
- Вы можете стать хорошо зарекомендовавшим себя специалистом, который потратил много времени и сил на фундаментальные вещи. Тогда вы сможете адаптироваться, переключать карьерные пути становится относительно легко. Вы можете заниматься машинным обучением, затем формальной верификацией, затем каким-нибудь низкоуровневым программированием для торговли или перейти в game dev. Это требует времени и самоотверженности — я бы оценил этот процесс минимум на 6-8 лет.
Я решительно выступаю за второй путь, потому что он более универсален, интересен и приносит больше в долгосрочной перспективе. Технологии постоянно меняется, поэтому вы захотите быстро переключаться на новые технологии.
Математика
Изучайте математику, потому что математика полезна. Я не могу это не подчеркнуть. Когда вы начнете, вы можете подумать, что вам не нужна линейная алгебра, потому что вы не знаете о приложениях. Однако для любого нетривиального машинного обучения вам это понадобится. Вам нужна статистика и вероятность. Вам понадобится логика, комбинаторика, теория множеств, все виды дискретной математики, теория графов, теория вычислимости, формальные грамматики, лямбда-исчисление, формальная семантика, топология, теории типов, теория чисел, группы, кольца, поля, категории.
Новые технологии постоянно появляются. Многие из них основаны на существующих математических моделях. Если вы хорошо знаете базовую математику, вы получаете очень приятные преимущества:
- Выбор среди новомодных технологий будет сделан на порядок проще.
- Вы поймете, где следует применять новые методы и где не следует.
- Вы будете понимать, почему решения такие, какие они есть. Затем вы сможете изменить их так, чтобы они лучше соответствовали контексту.
Например, у меня сложилось впечатление, что мало кто понимает почему вы не всегда должны использовать метод наименьших квадратов, чтобы оценить насколько хорошо ваша линейная регрессия соответствует данным. Это потребуется когда ошибки распределяются нормально с соответствующим средним значением. Если это не так, вы будете слепо применять неадекватное решение, даже не думая, что часть модели нуждается в настройке.
Изучите математику, чтобы научиться математическому мышлению. Написание доказательств делает вас строгим к своим действиям. Вы будете всегда думать обо всех возможных путях исполнения, которые может выполнять ваша программа, чтобы не привнести ошибки и проблемы безопасности. Ясность мышления, полученная от построения доказательств, драгоценна. Это также поможет вам написать короткий, сжатый код.
Учитесь на лучшем, используйте лучшие инструменты
Выберите свой первый язык. Он должен быть хорошо спроектированным, то есть иметь:
- Согласованность.
- Малое ядро.
- Отсутствие лишней сложности (например, при изучении «сложного» языка, есть вещи, о которых вы должны просто знать или постоянно помнить, они не приносят ничего полезного для обучения).
- Малую вероятность «выстрелить себе в ногу».
- Высокоуровневость, потому что программирование — это решение задач и проблем, а не мастерство в каком-то языке. Знать все маленькие особенности вашего любимого языка еще не значит быть совершенным в программировании.
Я советую выбрать один из следующих языков:
- Scheme (есть отличный классический вводный курс «Structure and Interpretation of Computer Programs»).
- Smalltalk
- Eiffel
- ML
Не бойтесь быть обманутыми кажущейся непопулярностью данных языков, в мире программирование популярность не означает качество.
Не начинайте с Питона, очень прошу вас! Он плохо спроектирован, непоследователен и не научит вас строгому мышлению. Не нужно привыкать к «хорошо, как правило, работающему» менталитету. Питон имеет свои применения, но не как первый язык.
Если вы привыкнете к некачественным языкам и некачественным инструментам, и некачественному программному обеспечению, и к некачественным решениям, вы неизбежно повторите их в своей собственной работе. Будьте критичны, задавайте вопросы, критикуйте все, ищите несоответствия и недостатки.
Например, представьте, что вы изучаете новый язык Go. Погуглите «Go language sucks» и почитайте почему люди критикуют его. Некоторые комментарии будут незначительными, но другие из них действительно будут иметь смысл. Вероятно, вы получите новые знания от чтения критических замечаний, оценивая их, чтобы потом определить имеют ли они значение, или это просто пустые слова.
Думайте сами
Я преподаю программирование (C и ассемблер) с 2009 студентам университета ИТМО в Санкт-Петербурге. У многих людей есть проблемы с программированием и никогда им не удается научиться этому из-за того, что они не создают код. Когда они получают задание, они пытаются имитировать существующее решение, возможно, взяв некоторые фрагменты из Stack Overflow, настроив их по своему вкусу. Хорошо, получили решение, что еще нужно?
Вы должны научиться писать код с нуля. Типы навыков, необходимых для этого, настолько отличаются от навыков, полученных вмешательством в существующий код!
Программировать значит делать сознательный выбор. Вы находитесь в состоянии А (у вас есть доступ к ряду языковых функций / библиотек, и вы знаете как их комбинировать); вы хотите получить состояние В (языковые конструкции объединены для решения задачи). Как вы построите маршрут от А до В? Теперь это реальное программирование, решение проблем.
Когда вы начинаете писать программы с нуля становится немного тяжело, но абсолютно необходимо научиться строить вещи с нуля. Чтобы улучшить навыки решения задач, важно изучить алгоритмы и структуры данных. Возьмите хорошую книгу и решайте олимпиадные задачи онлайн. Я рекомендую «Алгоритмы» Дасгупты для начала, затем классическую книгу Кормена. Все это откроет целый новый мир для вас, я обещаю.
Дополнительной частью процесса создания программного обеспечения является разработка архитектуры программного обеспечения; невозможно научиться правильно структурировать свои программы, не создавая их от 0 до 100.
Расширяйте свой кругозор
Программируйте каждый день, делайте сторонние проекты все время. Это очень простой (и в основном точный) способ для меня как учителя понять, что мой ученик с большой вероятностью добьется успеха. Один вопрос: что вы программируете в свободное время?
У ваших учителей просто не хватит времени, чтобы они смогли рассказать обо всем. В конце концов, после того, как вы выходите из университета, вы должны продолжать учиться самостоятельно, пока не уйдете на пенсию. Если вы увлечены тем, что вы делаете, вы будете изучать различные типы программного обеспечения для удовольствия, и это даст вам гораздо больше опыта и навыков, чем ваши менее мотивированные сверстники.
В идеале вы должны пробовать все: написать свой собственный компилятор, возможно, игрушечную ОС, http-сервер, движок для баз данных, игры, рейкастинг, создать какие-нибудь нейронные сети, написать простое мобильное приложение, написать программу для встроенных ..., можете сами продолжить. Поместите все свои проекты в GitHub и гордитесь ими: вам будующий работодатель может взглянуть на него. Используйте это портфолио в своих целях.
Общеизвестно, что рекрутинг хорошего программиста чрезвычайно сложен. У многих программистов, претендующих на работу, есть проблемы с написанием тривиальных вещей, таких как FizzBuzz. Если у вас есть существующие проекты, размещенные на GitHub, работодатель будет более уверен, что вы ему подходите.
Испытывайте себя разными инструментами и языками. Если кто-то говорит вам, что все языки похожи, это либо упрощение, либо отсутствие опыта. Позвольте мне объяснить немного.
Модель вычислений это множество, состоящее из базовых операций и способов склеить их вместе в порядок, необходимый для создания комплексных алгоритмов. Некоторые языки имеют очень похожие модели вычислений, а некоторые сильно различаются.
Программирование намного больше, чем общеизвестные C / Python / Java / C++ / C# / Go / Javascript, построенные на одинаковых принципах: императивный, структурный, немного с ООП и синтаксическим сахаром для имитации других стилей программирования. Мир программирования ОГРОМЕН. Как насчет:
- Промышленные функциональные языки программирования с комплексными и продуманными типовыми системами (Haskell, Ocaml).
- Функциональные языки с зависимыми типами, которые позволяют не только программировать, но и записывать доказательства (Coq, Agda, LEAN).
- Конкатенативные языки (Forth).
- Логическое программирование (Prolog, Refal).
- Конечные автоматы (регулярные выражения, Promela).
- Сильно расширяемые языки, позволяющие реализовывать практически любые синтаксические конструкции, как например Lisp, Forth, Camlp4/5, Rebol.
- Предметно-ориентированные языки (JetBrains MPS, XText).
Каждую новую модель вычислений трудно понять, потому что это новый способ мышления. Но потраченные силы и время стоят того.
Будьте общительными
Мне очень повезло познакомиться с некоторыми удивительными людьми. Мои помощники помогли мне совершенствовать свои навыки, учиться чему-то новому, видеть мир с другой точки зрения. Изоляция себя не принесет вам пользы в долгосрочной перспективе: вам нужно, чтобы другие люди обсуждали, чтобы понять, что они делают, что они думают.
Если ваш друг прочитал интересную статью и рассказал вам об этом, вы просто сэкономили много своего времени, потому что он дал вам обработанные, кристаллизованные знания.
Придерживайтесь страстных, умных людей и старайтесь учиться у них. Вы будете удивлены, сколько вы сможете узнать во время обеда со своими товарищами, которые хотят поделиться деталями своей работы или исследований. Такое разнообразие идей является одной из основных причин, по которым корпорации, такие как Google, дают вам бесплатное питание.
Спросите людей, которые лучше разбираются в code review и читают свой код. Изучая чью-то работу, можно многому научиться. Code reviews помогут вам узнать о том, как написать код еще лучше. Это, возможно, один из самых эффективных способов стать лучшим программистом очень, очень быстро.
Пишите тесты
Это так важно, что для этого понадобиться отдельная статья. Тестирование является неотъемлемой частью создания программного обеспечения, и даже такие парни, как я, которые работают над формально проверенным программным обеспечением (что означает, что оно должно быть математически строго формализуемо), пишут тесты, хотя можно подумать, что гарантии, данные доказательствами, гораздо сильнее.
Я надеюсь, что это может помочь кому-то получить более полную картину, быстрее научиться и стать лучшим программистом; если у вас возникнут вопросы, я буду рад помочь. Удачи!