Я уже пять лет обучаю наших сетевых инженеров Python. Не отправляю их на курсы по программированию для новичков, а выбираю именно формат внутреннего обучения. В этом посте я постараюсь дать развернутый ответ, чем мне не угодили массовые курсы, и расскажу об одном серьезном недостатке многих из них. Еще будет немного прикладной пользы для сетевых инженеров, которые самостоятельно хотят освоить Python и упростить себе работу.
Я работаю в центре сетевых решений. Это более 150 человек, из которых, по крайней мере, 100 — инженеры. Повседневная работа последних всё чаще требует применения инструментов автоматизации и скриптов. Увеличивается вес программной части внедряемых нами решений, повышаются требования к скорости их развертывания. При этом там, где раньше требовалось настроить одно устройство, сегодня нужно развернуть десятки и более типовых структурных элементов — виртуальных серверов, маршрутизаторов, межсетевых экранов.
Автоматизация необходима. Но это в теории. На практике же наши инженеры не спешат осваивать программирование самостоятельно, чтобы сделать свою работу проще: часто эта область кажется им сложной и непривычной. Я же, как главный конструктор и архитектор, всегда хотел, чтобы сетевые инженеры, работающие со мной на проектах, владели современным набором инструментов, а не только командной строкой. То есть могли писать скрипты под задачи и ориентировались в смежных областях: DevOps, SRE и др.
Для этого надо было упростить им вход в новую сферу, дать базовые инструменты и помочь получить первые результаты. Так мы с командой пришли к созданию собственного курса, как самого короткого пути к этой амбициозной цели — обучить (всех) наших инженеров программированию.
Python или Python
Для старта надо было выбрать язык программирования, который мы будем изучать. Я считаю, что в принципе нет критичной разницы, что выбрать для старта, поскольку главное — освоить именно само программирование, понять базовые основы, а сделать это можно на примере любого языка (языки, специально созданные для ненормального программирования, исключаем из рассмотрения).
Но был ряд обстоятельств и ограничений, которые привели к Python. В университете мы можем осваивать язык в течение нескольких семестров: сначала обучать студентов алгоритмизации, потом изучать прикладные вещи. Мы в центре сетевых решений не хотели превращать наших специалистов по инфраструктуре в разработчиков. Мы стремимся быстро, за пару недель, научить наших инженеров полезному в их работе навыку, да еще так, чтобы уже во время курса и сразу после него участники ощутили результат. То есть внедрили что-то в повседневную работу, и сразу что-то им стало лучше, быстрее, удобнее делать.
Python можно рассматривать как современный аналог Бейсика. Именно на Бейсике я написал в 1987 году свою первую программу. Этот язык создавался как раз для того, чтобы непрограммисты могли писать программы для решения своих задач. Для тех же целей сегодня отлично подходит Python. У него низкий порог входа, при этом он достаточно выразителен, чтобы писать на нем программы сразу «правильно», в соответствии с современными парадигмами.
Еще одно обстоятельство: вся автоматизация в OPS пишется именно на Python, именно под Python написаны основные библиотеки по управлению сетевым оборудованием, и именно этот язык часто можно увидеть в качестве встроенного языка в платформы популярных сетевых вендоров.
При таких вводных для сетевых инженеров лучшим выбором оказался Python, и за две недели реалистично научить людей с его помощью решать задачи.
Зачем нужен свой, когда уже есть тысячи других?
Наверное, самым важным при запуске любого внутреннего обучения становится вопрос о его необходимости. Зачем инвестировать в обучение тому, чему можно научиться на сотнях, если не тысячах уже существующих курсов?
У меня есть несколько аргументов в пользу внутреннего обучения:
Это, конечно, возможность кастомизировать курс под конкретные задачи компании или команды. Такая настройка «под себя» повышает эффективность обучения в несколько раз по сравнению с массовыми продуктами. В программировании циклы можно объяснять на примере решения задач про погоду и игры, а можно с самого начала решать задачи, моделирующие деятельность сетевого инженера. Например, на нашем курсе по Python я использую кейсы из практики «Инфосистемы Джет»: работу с сетевым оборудованием по SNMP, по REST API, анализ конфигов сетевого оборудования, построение таблиц IP-адресов. Это повышает прикладную полезность курса и сильно подстегивает мотивацию студентов. Они практически с первых дней понимают пользу осваиваемого навыка. И возможность вот так адаптировать общий навык к работе в конкретной компании или отрасли мне кажется ключевым фактором, определяющим необходимость запуска тематического внутреннего обучения.
Необходимость выбирать из множества онлайн-курсов и учебников может на старте тормозить людей, ведь надо выбирать подходящий источник из тысяч доступных, самому выстраивать процесс обучения и контролировать результаты. В случае внутреннего курса от них требуется лишь записаться на занятие, прийти на него и дальше двигаться по структурированному и уже проложенному другими пути из точки А в точку Б. И даже в этом случае необходимы личная мотивация и усилия, чтобы записаться, регулярно посещать занятия, делать лабораторные и совмещать всё это с загрузкой по проектам, с чем не все справляются.
Внутреннее обучение сильно ускоряет распространение навыка в компании и способствует росту экспертизы команды. Люди делятся впечатлениями от курса, мотивируют записываться других, помогают друг другу. Курс Python создавался под конкретные потребности нашего центра, но очень быстро вышел за его пределы. За эти годы я обучал не только сетевых инженеров, но и тестировщиков, сисадминов, специалистов по серверам, начинающих DevOps-инженеров и др. Мы в центре даже не ожидали, что наш узкоспециализированный курс будет так широко востребован. В этом году курс уже был трижды прочитан, а в листе ожидания еще 20+ человек. Я стараюсь обучать группы не более 12 человек, но оптимальное число студентов в одном потоке, на мой взгляд, — восемь. В таком составе преподаватель способен отследить прогресс каждого, помочь разобрать ошибки и дать персональную обратную связь.
Как и чему я учу сетевых инженеров
Кратковременные обучения в ИТ длятся в среднем 40 часов — это некий стандарт индустрии. Вендорские курсы не исключение: чаще всего они проходят в течение пяти дней по восемь часов. Треть этого времени отдается теории, остальное — практике.
Я ориентировался на это же количество часов, но разделил его на две недели. Каждый рабочий день мы занимаемся по четыре часа, чтобы не выдергивать полностью людей из процессов. Схема показала себя как жизнеспособная и удобная, и в эти сроки мы успеваем освоить все запланированное.
Научить человека программировать за две недели — это в определенной степени авантюра, но на положительный результат, конечно, влияет то, что все мои студенты — не люди с улицы. Одним приходилось уже что-то писать на языках программирования, другие представляют себе, как устроен компьютер — поэтому за 10 дней курса получается создать у наших инженеров более-менее целостное представление о программировании.
В рамках курса мы рассматриваем все основные синтаксические конструкции Python (кроме async, метаклассов и множественного наследования): что-то подробно разбираем, что-то лишь упоминаем. На каждую конструкцию я стараюсь подобрать пример, который можно показать «интерактивно» — в командной строке или в Jupyter Notebook. Сложные непривычные конструкции — вроде yield и декораторов — разбираем сразу с использованием отладчика. А на лабораторных работах стараемся сделать так, чтобы студенты «руками» несколько раз реализовали самые важные синтаксические конструкции: цикл, ветвление и функцию. Для тех, кто хорошо справился, добавляются еще генератор и декоратор.
Для лабораторных работ я стараюсь подбирать такие задания, сделав которые, студент получит результат и сможет применить инструмент сразу в работе. Мы на первом же занятии заводим аккаунты на GitHub тем, у кого до этого его не было. Студенты выкладывают туда все результаты, и у меня есть скрипт, который их анализирует. Но я еще обязательно смотрю сам, и дальше в личном порядке стараюсь разобрать с человеком на примере его кода, какие практики программирования хороши, а какие не очень, где сделано оптимально, а где лучше было бы сделать иначе.
Главная проблема курсов по программированию
Большинство массовых курсов по Python (да и по другим языкам тоже) на самом деле не про программирование. Они сосредотачиваются на изучении библиотек этого языка. Выбор библиотек определяется субъективными предпочтениями автора курса. На мой взгляд, важнее дать студентам понимание принципов, положенных в основу языка, к которому уже должны прилагаться практические навыки — например, умение использовать библиотеки.
С другой стороны, важно не уйти в крайность, когда в качестве задач используют слишком абстрактные и оторванные от реальной жизни примеры. Еще для такого прикладного курса важно найти требуемый баланс между сложностью и простотой учебного материала: не скатиться в примитивность и не провалиться в неоправданную сложность, превратив все в «олимпиадное» программирование, которое хорошо в других ситуациях.
У проектирования собственного курса есть значимое преимущество — ты можешь не повторять какие-то тиражируемые без конца неудачные паттерны. Например, во многих коммерческих образовательных программах отсутствует общетеоретическая часть о программировании. С моей же точки зрения, это самое важное в обучении языкам. Поэтому я стараюсь делать так, чтобы курс был не только о Python, но и о программировании вообще: как программы исполняются компьютером, как вообще принято писать код, что такое репозиторий и для чего всё это нужно.
Если человек получает набор разрозненных фактов и инструментов без понимания базовой концепции, то мы не оставляем шанса сформироваться системному мышлению. В дальнейшем, на практике, это приводит к тому, что человек не способен решить задачу, если ее условия сильно отличаются от учебных. В сети доступно множество качественных ресурсов, на которых человек может найти и скопировать нужный ему для решения задачи фрагмент кода. Но если что-то после этого копирования пойдет не так, человек без системного представления процессов не сможет разобраться в проблеме. Поэтому преподавателю нужно инвестировать время и усилия в то, чтобы студент мог выстроить системное представление о программировании и уже новые инструменты встраивал в эту систему. На мой взгляд, рациональнее это делать на самых первых этапах обучения. За две недели, естественно, сформировать такое комплексное и системное представление невозможно, но заложить некоторые основы для развития в правильном направлении — вполне.
Поэтому мы начинаем с того, что такое программа, код, данные и структуры данных, а также:
разбираемся, что такое интерпретатор, отладчик, репозиторий, среда разработки;
изучаем, как выполняются программы, как представляются данные и как оно в целом внутри компьютера устроено;
пытаемся понять, как из простых программ и элементарных структур данных создаются сложные программные комплексы.
Во второй части курса мы занимаемся более прикладными вещами — меньше учим сам язык и больше пробуем с его помощью решать задачи: организовать обмен по сети, написать маленький веб-сервер, извлечь какую-то информацию с оборудования или, наоборот, записать какую-то информацию на оборудование.
Об опасности рядового программиста
Программист, не понимающий сути программирования, опасен для себя и окружающих, особенно при современных подходах в программировании, когда простыми действиями легко можно создавать (и разрушать!) очень сложные структуры. И если не управлять этой сложностью, она имеет тенденцию быстро расти, и программист уже не может с ней справиться. Поэтому важно учить и учиться самим тщательно продумывать и делить задачи на части, выполнять их и тестировать, что получилось. Также важно донести до новичков понимание, что программный код пишется не для компьютера, потому что компьютеру более-менее всеё равно, какой код исполнять, а прежде всего — для самого себя и для других разработчиков. Потому что очень просто написать код, на который смотришь через день-два и вообще не понимаешь, что ты такое написал и как это может работать. Неосторожными действиями можно очень резко нарастить сложность, с которой будет невозможно справиться.
Особенно остро последствия таких действий проявляются в промышленном программировании, когда мы имеем дело с системами, которые создавались в течение многих человеко-часов большими командами. Каждый участник такой проектной команды понимал и делал задачу «в меру своей испорченности», внося дополнительную системную сложность и баги. Если еще всё это плохо задокументировано, то задача поддержки такой системы становится очень трудной. Тем, кто продолжит её развивать, придется тратить часы и дни, чтобы разобраться, что и зачем написали предшественники. Чтобы сократить эти ненужные издержки и проблемы, нужно уже в самом начале обучения формировать комплексное представление у человека о том, как его действия влияют на систему.
Это, конечно, актуально именно для курсов, где целенаправленно готовят разработчиков, но и даже после курса прикладного программирования для непрограммистов, как наш, выпускники должны понимать свои возможности и ограничения. И если программирование «зашло», то представлять, в каком направлении и как дальше развиваться.
Что я использовал для других, а вы можете применить для себя
После того, как принято решение о запуске внутреннего курса, следующий важный вопрос — как и на основе чего составить программу. Мы ориентировались на наши повседневные потребности в проектах. Но есть и более универсальные источники, которые мы в том числе использовали в подготовке. Приведу список, который могу рекомендовать сетевым инженерам для самостоятельного изучения:
Марк Лутц «Изучаем Python». Классический англоязычный труд, который регулярно переиздается на русском языке. Из него я взял описание Python как языка.
Курс Наташи Самойленко «Python для сетевых инженеров». У Наташи есть YouTube-канал и множество коммерческих продуктов на эту тему: учебник и курсы. Это уже совсем близко к нашим целям, но подача теории здесь не совсем соответствует моим представлениям об идеале. А вот практическая часть хороша: речь идет именно о тех библиотеках и возможностях языка, которые востребованы в работе инженеров.
Андрей Столяров «Программирование — введение в профессию». Автор работал у нас в «Инфосистемы Джет», долгое время преподавал на кафедре алгоритмических языков факультета вычислительной математики и кибернетики МГУ. Это фундаментальный трехтомный труд, из которого я очень много взял с точки зрения систематизации знаний у моих студентов. Он содержит объяснение основ программирования и обеспечивает понимание того, как программы создаются и как они должны создаваться, что такое хорошо и что такое плохо в программировании. Справедливости ради стоит отметить, что автор язык Python не любит и считает, что учить программировать на нем нельзя, потому что потом получаются специалисты с испорченной психикой и для промышленного программирования непригодные. Мы не стремимся подготовить за две недели разработчика для Enterprise — у нас более скромные и прикладные задачи, для которых Python хорошо подходит. Но труд Андрея Столярова вовсе не для изучающих конкретный язык, а для всех, кто пишет или собирается писать программы длиннее ста строк.
Как обучаться самому
Для начала можно посмотреть несколько роликов на YouTube, поставить Python и попробовать по этим роликам сделать простые вещи.
Как только чему-то научились, можно начать читать книгу Марка Лутца.
Как только прочитали и осмыслили, что в ней есть, надо продолжать писать код. Желательно такой, который будет решать ваши реальные задачи, а лучше — задачи вашей команды. Для этого сетевым инженерам и пригодится курс и другие ресурсы Наташи Самойленко.
Можно потренироваться на задачах и упражнениях (например, на checkio.org), чтобы уверенно освоить синтаксис языка и базовые алгоритмы. На этом этапе также полезно посмотреть вокруг — какие еще есть языки, кроме Python.
Если научились писать программы длиной хотя бы в пару сотен строк, стоит начать читать монографию Столярова. В самостоятельном обучении также нужно не пропустить эту часть с пониманием базовых принципов программирования — ведь именно она, а не знание отдельных функций, сделает из вас программиста.
Максим Клочков
Руководитель группы проектирования решений по передаче данных Центра сетевых решений
«Инфосистемы Джет»