Программирование
3 навыка лучшего инженера по программному обеспечению
Виктор Савкин является со-основателем nrwl.io, предоставляя консультации по Angular командам предприятий. Ранее он работал в команде Angular Core в Google, и сделал модули инъекции зависимостей, отслеживания изменений, форм и роутеров.
Когда меня спрашивают «Как стать хорошим инженером-программистом?», я обычно рекомендую развивать следующие три направления:
- Деление и упрощение.
- Хорошие ментальные модели.
- Инструменты.
Не поймите меня неправильно, здесь нет какой-то волшебной таблетки – для того, чтобы стать достойным инженером, требуется много лет целенаправленной практики. Три вышеперечисленных навыка – это то, что практикуют самые лучшие инженеры. Почти без исключения – когда я интервьюирую человека, который хорошо разбирается в этих трех направлениях, я знаю, что он станет замечательным инженером.
Делите и упрощайте
Делите
Поскольку мы не можем удерживать более 5-7 объектов в рабочей памяти, любая нетривиальная проблема слишком велика, чтобы держать ее в голове. Мы можем либо абстрактно осмыслить проблему в целом, либо детально рассмотреть небольшую часть проблемы. Оба способа важны. Также важно знать уровень абстракции, на котором вы сейчас работаете. Либо мыслите абстрактно, используя большие метафоры и аппроксимации, или думайте точечно. Старайтесь не смешивать такие подходы.
Вот процесс, который я использую при разделении проблемы на подзадачи:
Шаг первый: удостоверьтесь, что вы понимаете проблему.
- Распишите проблему на бумаге.
- Запишите все ограничения, о которых вы знаете.
- Запишите то, что вы не знаете, но что могло бы быть полезным. Найдите такие вещи.
Шаг второй: нарисуйте диаграмму проблемной области.
- Несколько прямоугольников и стрелочек, ничего необычного.
- Эта диаграмма должна дать вам представление о том, как разделить проблему на подзадачи.
- Найдите способ нарисовать диаграмму, которая по-разному делит проблемную область. Если вы не можете этого сделать, вы, вероятно, недостаточно хорошо понимаете проблему.
- Выберите один из способов деления проблемы.
Шаг третий: выберите подзадачу и используйте тот же процесс, чтобы разделить его дальше.
- Остановитесь, когда проблемы (проблемный субдомен) станут малы и понятны.
- Решите их индивидуально и объедините результаты.
Упрощайте
Разделение хорошо работает при решении сложных проблем, потому что каждое деление удаляет один слой. Реальные системы не только глубокие, но и широкие.
Это означает, что, хотя вы, возможно, находитесь на правильном уровне абстракции, для решения проблемы все еще слишком много деталей. В этом случае возьмите проблему и придумайте простую репродукцию, иллюстрирующую проблему. Решите ее в этом упрощенном контексте, а затем примените исправление к реальной проблеме.
Представьте, что вы изучаете проблему производительности. Скажем, деля проблему снова и снова, вы выяснили, что проблема связана с сеткой компонентов. К сожалению, у вас есть десятки и десятки строк, созданных в таблице, которые мешают вашему исследованию. Проведя час, пытаясь найти решение, сделайте шаг назад, чтобы найти способ упрощения. Создайте новое приложение, используя эту сетку, воспроизведя проблему. Упростите ее до максимума (например, может быть, один столбец с текстом). Используйте решение, чтобы устранить проблему, а затем применить исправление к ситуации в реальной ситуации.
Используйте научный подход
Используйте научный подход, чтобы улучшить понимание проблемы. Он работает следующим образом:
- Запишите вопрос, на который вы пытаетесь ответить.
- Запишите гипотезу.
- Запишите прогноз, которое является результатом гипотезы.
- Проверьте прогноз и запишите результат.
- Повторяйте, пока не получите ответа на вопрос.
Представьте, что мы создали упрощенное приложение с использованием грид-компонента. Теперь мы можем использовать научный метод, чтобы выяснить, почему он тормозит.
Запишите вопрос: почему для рендеринга сетки требуется 5 секунд?
Подумав об этом некоторое время, мы можем получить следующую идею: может быть, обнаружение изменений работает слишком много раз? Это наша первая гипотеза, поэтому давайте ее запишем.
Прогноз, который мы можем использовать для проверки гипотезы, заключается в том, что appRef.tick будет несколько раз проявляться в профайлере.
Мы проводим эксперимент, и результат подтверждает нашу гипотезу. Давайте запишем его.
Теперь, к следующему вопросу: почему обнаружение изменений выполняется сотни раз?
Шаги 1, 3, 4 этого процесса хорошо определены. Они выполняются почти механически. Шаг 2 – выдвижение гипотезы – это то, где происходит творческая работа. И здесь хорошие ментальные модели и интуиция очень помогают.
Все инженеры умеют программировать, но не все программисты могут быть инженерами: в чем отличие?
Развивайте хорошие ментальные модели
«Точка зрения дает нам 80 баллов IQ» Алан Кей
Ученик средней школы, который знает основы алгебры, геометрии и исчисления, может решить больше математических задач, чем талантливые математики древнего Рима. Это не потому, что студент «умнее». Его IQ не выше. Он может это сделать, потому что у него хорошие ментальные модели.
Разработка хороших ментальных моделей – одна из самых важных инвестиций, которую мы можем сделать в качестве инженеров. Например, посмотрите на этот список:
- Язык программирования.
- Программа.
- Компилятор.
- Система типов
- Функциональное программирование, императивное, логическое программирование.
- Виртуальная машина
- Интерпретатор
- Сборка мусора
- База данных.
- Распределенная система
- Обмен сообщениями.
У вас есть хорошие ментальные модели для всех из них?
Иметь хорошую ментальную модель X, не означает, что вы должны быть экспертом в X. Это означает, что вы можете нарисовать диаграмму, показывающую, как работает X, и, если дано достаточно времени, может построить простую версию X.
Ментальные модели, представленные выше, являются общими. Вот некоторые ментальные модели, ориентированные на frontend:
- Bundling.
- Treeshaking.
- Change detection.
- Observable objects.
- Virtual DOM.
- CQRS/event sourcing/Redux.
Разработка ментальных моделей
Как можно развить хорошие ментальные модели?
Читайте
Во-первых, много читайте. Читайте книги, читайте статьи.
Используйте «узкие» технологии
Во-вторых, найдите технику, которая делает именно ту вещь, которую вы пытаетесь изучить, и делает только это. Если вы пытаетесь изучить функциональное программирование, возьмите Elm и потратьте неделю, пытаясь решить проблемы вместе с ним. Поскольку Elm чист, он не позволит вам использовать обходные пути – вам придется делать все по книге. Вы также не будете отвлекаться на сложность более универсального инструмента, такого как Scala.
Создавайте их сами
Наконец, создайте упрощенную версию того, что вы пытаетесь изучить с нуля. Хотите узнать что-то о компиляторе? Создайте свой собственный компилятор. Хотите изучить логическое программирование? Создайте собственный интерпретатор Пролога. Изучаете распределенные системы? Создайте крошечную программу, иллюстрирующую передачу сообщений между различными узлами в системе. Используйте ее, чтобы узнать о CAP.
Требуется год для создания компилятора распространенного языка программирования. Это потому, что вы хотите, чтобы он был быстрым, всегда корректным и обрабатывал все странные краевые случаи в языке. Взяв более простой язык (например, некоторые варианты Lisp) и игнорируя проблемы с производительностью, вы можете сделать это за один день.
Обратите внимание, что это игра, поэтому вы не можете здесь потерпеть неудачу. Вам не нужно ничего поставлять на рынок. Единственная цель этого – ваше обучение. Поэтому, даже если вы не закончили свой компилятор, но вы многому научились – вы на правильном пути.
“Должности ничего не значат”: чем отличается разработчик от инженера?
Изучите свои инструменты
Инженеры-программисты – профессионалы, которые полагаются на инструменты. Вот некоторые из инструментов, которые я использую каждый день:
- Клавиатура.
- Операционная система.
- Оболочка.
- Редакторы и IDE.
- Менеджер пакетов (brew, npm, yarn, …).
- Языки (typescript, css, …).
- Инструменты разработчика (инструменты Chrome Dev, отладчик node…).
- Фреймворки и инструменты (angular, rxjs, webpack, rollup, …).
В то время как ментальные модели абстрактны, инструменты являются конкретными. Вы можете хорошо разбираться в VSCode, но ничего не знать о VIM, хотя оба являются текстовыми редакторами. Для изучения новой раскладки клавиатуры или освоения IDE требуется несколько месяцев или даже лет. Вот почему этот список намного более узкий.
Есть две причины хорошо изучить свои инструменты:
Вы более эффективно выполняете задачи, если знаете правильные инструменты. Если вы хорошо знаете Angular, то можете создать простое приложение за час, без использования материалов Google. Аналогичным образом, вы сможете быстрее устранить проблему с отладчиком по сравнению с отладкой с помощью логов в консоли.
Еще более важной причиной для изучения ваших инструментов является то, что вы можете использовать их не задумываясь. Возьмите быстрые клавиши в редакторе. Использование шорткатов в редакторе лучше не потому, что это быстрее (хотя так и есть), а потому, что вы можете использовать их автоматически, без необходимости проходить через меню, не задумываясь об этом вообще. Таким образом, ваш разум свободен и может думать о реальной проблеме.
Хорошее понимание инструментов вовсе не означает, что все, что вы используете, должно быть привычным. Я использую эргономичную программируемую клавиатуру, потому что я много времени думал о том, как мои пальцы двигаются при наборе текста.
Я считаю, что следующее истинно:
Любой инженер, который хорошо знает свои инструменты – это хороший инженер. Человек, который не знает своих инструментов хорошо, вряд ли будет хорошим инженером.
Вы должны быть больше, чем просто хорошим инженером
Освоение трех навыков не означает, что вы будете эффективны на своей работе или окажете существенное влияние на продукт. Способности устранить ошибку или написать новую библиотеку недостаточно для того, чтобы стать профи. Вот некоторые другие навыки, что важны не меньше:
- Ваши социальные навыки. Самые интересные проекты построены командами. Они построены людьми с разными навыками, опытом и личностями. Вы должны иметь сильные социальные навыки для работы в таких условиях.
- Ваши навыки письма. Вы должны сообщать свои идеи своей команде, вашим клиентам и сообществу. Письмо – это наиболее масштабируемый способ сделать это. Практикуйтесь в письме.
- Ваша трудовая этика.
- И многое другое.
Желаем вам удачи!