Svartsinn1
Programming. Как оперативно выучить язык программирования?

Самиздат: [Регистрация] [Найти] [Рейтинги] [Обсуждения] [Новинки] [Обзоры] [Помощь|Техвопросы]
Links
Кожевенное мастерство: сумки, ремни своими руками
 Ваша оценка:

Пятница, утро, и на вас падает задача в проекте, где основной язык вы никогда не писали. Может это Go, может Rust, может встроенный DSL, который в компании зовут "конфигом", хотя это полноценный язык с компилятором и ошибками. Дедлайн через две недели. Первый порыв понятен: открыть учебник с первой страницы и начать проходить синтаксис по параграфам, как в школе проходили иностранный. Этот порыв и есть главная ошибка, потому что школьная методика рассчитана на годы и на отсутствие дедлайна.

Хорошая новость в том, что мозг уже располагает готовым аппаратом для такой работы. В 2020 году группа нейробиолога Шантель Прат из Университета Вашингтона опубликовала в Scientific Reports эксперимент, где взрослые люди без опыта программирования за десять сессий осваивали Python. Предиктор успеха искали среди разных кандидатов: числовой интеллект, рабочая память, логика. Сильнейшим оказался лингвистический потенциал, измеренный классическим тестом MLAT, который применяют при отборе на изучение иностранных языков. Математика проиграла языковому чутью. Рисунок активности мозга в покое, снятый до начала обучения, позволял заранее выделить тех, кто выучится быстро. Программирование оказалось для мозга чем-то куда более похожим на второй язык, чем принято думать.

Из этого факта следует целая стратегия. Если язык программирования осваивается теми же механизмами, что и иностранная речь, то к нему применимы методы, отработанные десятилетиями исследований усвоения второго языка. Закономерности забывания и эффекта тестирования, механика имитации образцов, роль чтения до начала письма. Эти методы почти никто не использует, потому что культура обучения программированию застряла в парадигме "сначала весь синтаксис, потом проекты".

Дальше разберём, как устроено чтение кода глазами эксперта, что именно стоит заучивать, а что вечно держать в справочнике, и как выстроить первые сорок часов работы, чтобы не узнать сто слов из учебника, а начать писать своими руками.

Иностранный язык, подтверждённый томографом

Свидетельств того, что код обрабатывается речевыми механизмами, накопилось достаточно. В 2020 году лаборатория Марины Бедни из Университета Джонса Хопкинса опубликовала в eLife фМРТ-исследование, где участники читали и оценивали короткие программы на Python. Задействовались как классические "языковые" зоны коры, так и лобно-теменная сеть, которую нейробиологи называют multiple demand, "многозадачной". Она же включается при логическом выводе и решении новых задач. Метаанализ фМРТ-исследований понимания программ, опубликованный группой Ёсихару Икутани в 2021 году, подтвердил картину: понимание кода опирается одновременно на "речевые" и "математические" сети.

Практический вывод двойственный. С одной стороны, к языку программирования применимы приёмы из освоения иностранного: словарь заучивают порциями, чтение предшествует письму, имитация предшествует свободной речи. С другой стороны, код требует трассировки, то есть прокрутки состояния в голове. Это отдельный навык, и он тренируется отдельно. Частая ошибка новичка в том, что он пытается совместить обе нагрузки сразу: одновременно разбирать незнакомый синтаксис и следить за данными. Рабочая память захлёбывается, и ни одна из задач не выполняется.

Стратегия, вытекающая из нейробиологии, проста. Разнесите две нагрузки по времени. Сначала только парсинг: научиться узнавать конструкции и угадывать их смысл без трассировки. Потом только трассировка на уже знакомом синтаксисе, когда глаза не спотыкаются о слова. Так читает ребёнок: пока он занят дешифровкой букв, смысл произведения тонет. Фаза беглого чтения должна прийти раньше фазы глубокого анализа.

Четыре слота рабочей памяти, или почему не надо учить всё

Классическая цифра Джорджа Миллера из статьи 1956 года: семь плюс-минус два элемента удерживаются одновременно. Современные оценки скромнее. По данным Нельсона Кована (2001), рабочая память вмещает около четырёх смысловых единиц, чанков. Фелине Херманс, исследователь из Утрехтского университета, в книге The Programmer's Brain (2021) показала, что чтение кода упирается именно в этот сосуд. Программист забывает значение переменной к моменту, когда она возникает в двадцатой строке, и стоимость забывания измеряется минутами перечитывания.

Отсюда жёсткое следствие для планов обучения. Заучивать весь словарь языка бессмысленно и даже вредно, потому что он вытесняет из ограниченной памяти то, что обязано быть под рукой. Разделите лексику на ядро и справочник. Ядро извлекается мгновенно: переменные и присваивание, условный переход, циклы, функции и возврат значения, базовые коллекции, обработка ошибок, импорты. Восемь тем, на освоение которых активным письмом уходит несколько дней. Справочник - всё остальное: стандартная библиотека, сигнатуры, флаги форматирования, тонкости синтаксиса.

Проверьте себя на бумаге без редактора. Выпишите столбцом эти восемь тем и против каждой поставьте плюс только в том случае, если конструкция пишется из памяти за пять секунд. Всё, что не получило плюса, идёт в план ближайших дней, остальное вычёркивается из списков на заучивание. Человек, честно проведший такой аудит, обычно обнаруживает, что заученное им и нужное ему пересекаются процентов на тридцать. Остальные семьдесят усилий ушли бы в зону справочника, куда можно заглянуть и без зубрёжки.

Заглядывать в справочник - не признак слабости, а часть профессии. Сеньор с пятнадцатилетним стажем не помнит порядок аргументов у редкой функции, и это нормально. Асимметрия информации давно решена в пользу "знать, где искать": помнить надо карту местности, а не каждый дом. Катастрофа случается, когда человек не помнит даже карты и ищет каждый раз с нуля. Тест на зрелость в новом языке звучит так: можете ли вы без подсказок написать цикл по коллекции, условный выбор и функцию с двумя параметрами. Если да, ядро собрано и можно двигаться дальше.

Когда сам язык мешает учиться

Есть нюанс, о котором почти не говорят на курсах. Трудность освоения - не всегда ваша заслуга, часто это свойство конструкции самого языка. Андреас Стефик и Андреа Сиберт на конференции OOPSLA в 2013 году опубликовали жёсткий по методике эксперимент. Новички без опыта писали программы на разных языках, включая специально сконструированный Randomo. Его синтаксис генерировался случайно: ключевые слова заменялись произвольными символами. Ожидалось, что любой нормальный язык окажется сильно лучше бессмыслицы. Ожидали зря. Точность задач на Perl оказалась статистически неотличима от Randomo. А вот язык Quorum, чей синтаксис годами проверялся на живых людях эмпирически, дал заметно лучший результат.

Вывод стоит проговорить спокойно. Значительная часть боли при освоении популярных языков - не тупость учащегося, а исторический багаж дизайна, который никто не тестировал на новичках. Церемония Java из пяти строк на один вывод в консоль, трёхэкранные диагностические сообщения компилятора C, перегруженный синтаксис C++ не измерялись экспериментально, они просто достались в наследство. Осознание этого факта экономит эмоциональные ресурсы. Вместо самобичевания "у меня не получается" появляется точная формулировка: "этот интерфейс спроектирован плохо для моей задачи".

Практических правил три. Если выбор первого языка за вами, берите тот, где пишут коротко и сообщения об ошибках человеческие. Если язык навязан работой, снизьте планку на первые две недели и не судите свой интеллект по скорости. И третье: читайте сообщения об ошибках целиком, как читали бы незнакомое предложение на иностранном. Компилятор - единственный носитель языка, доступный бесплатно круглосуточно, который никогда не устаёт объяснять грамматику.

Как эксперты читают: не строка за строкой, а пятнами

Тереза Бушан с коллегами опубликовала в 2015 году на конференции ICPC исследование движений глаз с говорящим названием "Расслабление линейного порядка". Новичкам и экспертам давали короткие тексты и фрагменты Java, записывая траекторию взгляда. Читая английский текст, обе группы двигали глазами слева направо и сверху вниз одинаково. На коде картина раскололась. Новички продолжали читать программы как прозу, строка за строкой. Эксперты ходили по коду прыжками: к первым строкам объявлений, назад к вызову, вперёд к закрывающей скобке. Линейность чтения падала, а понимание росло.

Механизм такого чтения описан ещё в работе Чейза и Саймона о шахматистах (1973). Гроссмейстер восстанавливает по памяти позицию на десятки фигур лучше новичка, но только пока позиция осмысленная. Из случайной расстановки он запоминает не больше любителя. Значит дело не в объёме памяти, а в единицах восприятия. Мастер видит не тридцать две фигуры, а пять-семь смысловых блоков: "структура королевского фланга", "висячая пешка", "вилка". Точно так же опытный программист видит не девять операторов, а один чанк: "чтение файла с защитой от отсутствия".

Это меняет задачу обучения радикально. Учить надо не строки, а идиомы: устоявшиеся конструкции из трёх-семи элементов, которые читаются целиком. Списковое включение, безопасное открытие файла, цепочка проверок через ранний выход, обход словаря в цикле. Вот две записи одной и той же операции на Python, сначала буквально, потом чанками.

result = []
for item in orders:
    if item.is_paid:
        result.append(item.total * 0.8)

paid_discounted = [item.total * 0.8 for item in orders if item.is_paid]

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

Теперь алгоритм чтения незнакомого файла в чужом проекте. Первый шаг - поведение, а не текст: найдите тесты или запустите программу, чтобы понять, что она делает. Второй - точка входа: функция main, обработчик маршрута, колбэк кнопки, но не зависимости сразу. Третий - карта: пробегитесь только по именам функций и классов, игнорируя тела, оцените рельеф модуля. Четвёртый - данные: найдите, откуда вход приходит и где превращается в выход, и двигайтесь по этой линии. Пятый - укол инструментом: вместо многострочной трассировки глазами поставьте точку останова в отладчике и шагните пять шагов. Глаза дешевле паники, но отладчик дешевле глаз.

Припоминание через интервалы вместо перечитывания

Самый дорогой по неэффективности способ учить - перечитывание, самый выгодный - припоминание. Родигер и Карпике в Psychological Science (2006) показали эффект тестирования. Студенты, прочитавшие текст один раз и потом дважды себя проверявшие, через неделю удержали заметно больше тех, кто перечитал материал четыре раза. В перечитывании есть ловушка беглости: текст знаком, глаз скользит, уверенность растёт, а знаний нет. Для иностранной лексики существует обширный пласт результатов по интервальному повторению. Свежий пример - исследование Марианы Макис и коллег (2021) о разнесённых повторах при заучивании коллокаций второго языка: интервалы стабильно выигрывают у повторов подряд.

Что из этого следует для программиста. Сделайте маленький набор карточек с идиомами, но с важным отличием от школьных карточек. На одной стороне не вопрос из серии "как называется декоратор", а микро-задача: "напиши открытие файла с гарантией закрытия при ошибке", "переверни список", "проверь ключ в словаре и дай значение по умолчанию". Припоминание должно требовать производства текста, а не узнавания. Пять карточек по десять минут в день на протяжении месяца дают больше, чем выходные с учебником, потому что интервалы сильнее плотной зубрёжки.

#!/usr/bin/env python3
# десять минут разминки перед работой:
# 1) напиши из памяти dict.get с дефолтом
# 2) напиши списковое включение с условием
# 3) напиши with open(...) не заглядывая в IDE
# сверился, закрыл, пошёл работать

Похожая ловушка устроена вокруг автодополнения. Сламека и Граф описали ещё в 1978 году эффект генерации: слово, которое человек произвёл сам, запоминается лучше прочитанного в готовом виде. Когда среда подсказывает метод за две буквы, она оказывает обучению медвежью услугу: код пишется быстро, а словарь не закрепляется. На время интенсивного освоения языка автодополнение уместно глушить хотя бы разминки, чтобы рука сама вспоминала конструкцию целиком.

От подражания к собственному слогу

В методике обучения письму на иностранном языке давно отработана лестница: имитация, адаптация, порождение. Сначала переписываешь чужой образец, потом меняешь в нём элементы под свою задачу, потом пишешь своё с опорой на накопленные шаблоны. Код подчиняется той же лестнице. Сначала вы руками перепечатываете короткий рабочий фрагмент из документации или живого проекта, добиваясь прохода без ошибок. Потом меняете в нём условия: другой формат входа, другой критерий фильтрации. Потом пишете похожую утилиту с нуля, заглядывая только в сообщения об ошибках.

Каждая ступень обязана даваться с трудом определённой интенсивности. Андерс Эрикссон, автор концепции осознанной практики (deliberate practice, 1993), формулирует требование точно: задача строго чуть выше текущего уровня, немедленная обратная связь, повторный заход с поправкой. В программировании обратная связь доступна бесплатно и мгновенно: интерпретатор, REPL, тесты, линтер. Ученик иностранного языка узнаёт о своей ошибке от собеседника через неловкое молчание, а вы - через полсекунды от компилятора.

Конкретная форма практики - портирование собственной утилиты. Возьмите маленький скрипт, который сами написали раньше на знакомом языке: парсер лога, генератор отчёта, переименование файлов. Размер в сто-двести строк, не больше. Перепишите его на новом языке, не подсматривая в оригинал и держа логику в голове. Задача кормит три канала сразу. Вы производите код, что включает эффект генерации. Вы ограничены рамками уже решённой задачи, то есть остаётесь в зоне "чуть выше уровня". Вы собираете личный словарь идиом, потому что каждая недостающая фраза встаёт на своё место в реальном тексте, а не в абстрактном упражнении.

Одно предостережение по календарю. Не начинайте два похожих языка в один месяц. Там, где совпадает половина синтаксиса, идиомы путаются, и интерференция бьёт по обоим словарям сразу. Классическая ловушка - параллельное штудирование Java и C# или Java и JavaScript в надежде "закрыть сразу два требования вакансии". Исследования усвоения второго языка фиксируют, что интерференция сходных форм отнимает больше сил, чем даёт экономия на общих корнях. Осваивайте языки последовательно с промежутком в два-три месяца, когда первый уже держится на чанках, а не на сознательном вспоминании.

Отдельного упоминания заслуживает работа с ошибками как учебный режим. Исследования студентов в курсах программирования фиксируют связь эпизодов путаницы с ростом понимания: кто периодически тонул в непонимании и выбирался, удерживал больше тех, кто ехал по гладкой дорожке. Свои ошибки стоит вести списком с формулировкой "какое правило языка я выучил за счёт этого стектрейса". Через неделю журнал превращается в персональный конспект, составленный не методистом, а самим языком через синяки.

План на первые сорок часов

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

С одиннадцатого по двадцать пятый час фокус смещается на чтение и только на чтение. Открываете один небольшой проект с живой кодовой базой, лучше консольную утилиту на пару тысяч строк, и проходите её по алгоритму из раздела про взгляд эксперта: тесты, точка входа, карта имён, линия данных, отладчик. Цель блока - наращивание чанков. Встреченные идиомы выписываете в набор карточек и разгоняете их интервалами по одной-две минуты в перерывах. Двадцать пятый час - контроль чтения: открываете новый модуль проекта и объясняете его вслух за пять минут.

Оставшиеся пятнадцать часов - режим порождения. Первые пять уходят на портирование своей маленькой утилиты. Следующие пять - небольшая собственная штука строк на двести: скрипт, бот, генератор данных, то, что лично вам нужно ежедневно. Последние пять можно перемежать с настоящим контекстом: первый рефакторинг в чужом коде, одна добавленная функция, первый pull request. На этом рубеже вы уже читаете язык не со словарём, а со справочником. Восемьдесят процентов глаголов живого языка покрываются тремястами корнями, и ядро программного языка ещё компактнее.

Скорость - не талант, а договор с ресурсами

Сведём линию воедино. Мозг читает код тем же аппаратом, что и естественную речь, а значит осваивать язык надо как язык: сначала беглое чтение, потом порождение, с имитацией посередине. Память конечна и вмещает четыре чанка единовременно, поэтому заучивать надо только карту и ядро, остальное оставляя поиску по требованию. Скорость чтения растёт не от количества просмотренных строк, а от укрупнения единиц восприятия, которые глаз опознаёт пятнами, а не побуквенно.

Перечитывание обманывает счётчиком беглости, поэтому его заменяют припоминанием с интервалами, а автодополнение на время обучения глушится в пользу медленного письма. Трудности синтаксиса возвращаются к проектировщикам, а не к вашему интеллекту. Обратная связь бесплатна и мгновенна, а путаница при ведении журнала ошибок конвертируется в знание по фиксированному курсу.

И последнее. Язык программирования - искусственная конструкция, придуманная людьми для людей. Он заключает с вами негласный договор: не оценивать ваше достоинство, а просто выполнять прочитанное. Это соображение ставит страхи на место. Скорость чтения на третьей неделе - не приговор и не уровень, а стадия того же процесса, который прошёл любой носитель этого языка. Язык не судья. Язык - инструмент, и обязанности у инструмента ровно те, что человек сам в него заложил.


 Ваша оценка:

Связаться с программистом сайта.

Новые книги авторов СИ, вышедшие из печати:
О.Болдырева "Крадуш. Чужие души" М.Николаев "Вторжение на Землю"

Как попасть в этoт список

Кожевенное мастерство | Сайт "Художники" | Доска об'явлений "Книги"