У программистов есть разные поговорки о трудных проблемах. Наверное, мой любимый вариант: «В информатике две трудные проблемы: недействительность кэша, присвоение имён и ошибки на единицу».
Я пишу программное обеспечение достаточно давно, чтобы столкнуться с каждой из этих проблем. В то же время я выступаю со стороны бизнеса и объясняю клиентам техническую часть нашего продукта, поэтому постоянно сталкиваюсь с непрограммистами. Самое важное — правильно передать идею или концепцию таким образом, чтобы другие её поняли.
А это очень трудно.
Как и во всех профессиональных сферах, программисты разработали собственный жаргон для быстрой передачи концепций.
Жаргон очень важен. Если мы с коллегой выбираем алгоритм для решения конкретной задачи, то можем сказать, что «первый вариант
Это единственное предложение многое говорит, для каких сценариев следует использовать алгоритм и как они реализуются под капотом:
Как видите, мы смогли передать несколько абзацев информации в одном предложении, просто используя правильные термины.
Но если у вас встреча с людьми из-за пределов мира программирования (например, инженеры-механики или электрики, менеджеры, маркетологи), этот технический жаргон только оскорбит и запутает людей, не передавая почти никакой ценной информации.
Это то, что я называю технолепетом, бормотанием программиста.
Скажу прямо, обычно эти детали и термины не нужны людям из других областей, и им действительно всё равно.
Например, вы объясняете удивительную новую функцию, которая находит кратчайший путь от A до Б, генерируя навигационную сетку и применяя поиск A*.
Ни в коем случае не нужно описывать новую функцию как в предыдущем предложении. Вместо этого скажите что-то вроде такого: «Мы вычисляем кучу возможных путей, а затем применяем умные алгоритмы, которые используются в игровой индустрии, чтобы найти лучший маршрут».
Не имеет значения, что мы здесь используем именно поиск A* (в отличие от алгоритма Дейкстры или поиска по ширине). Неважно, что в играх поиск A* используется не только для перемещения персонажей. Собеседнику достаточно знать, что вы можете найти хороший путь от А до Б и что мы используем надёжные инструменты, уже проверенные в других областях.
Не мешает показать иллюстрацию, что вы имеете в виду…
Мне случалось наблюдать, как более опытные программисты используют техножаргон для демонстрации превосходства, чтобы показать свой невероятный интеллект и установить доминирование. Это действительно раздражает.
Не поймите неправильно, иногда бывают ситуации, когда достаточно компетентный собеседник спрашивает: «Это очень сложно, почему просто не сделать X?» — и вам придётся показать, что вы здесь эксперт, а он не знает, о чём говорит… но всё равно это можно сделать разными способами.
Не пытайтесь использовать технолепет для удовлетворения своего эго, он подвергает людей остракизму и позорит нашу профессию.
Так мы плавно переходим к следующему пункту… не забывайте об уважении.
Многие люди, с которыми я работаю, действительно умны и эксперты в своих областях, но необязательно у них хватает знаний и опыта в создании информационных систем.
Объясняя сложную проблему, зачастую лучше упростить понятия. Но старайтесь не быть снисходительным.
Тот инженер-программист, о котором я упоминал, часто отвечал: «Это… сложно», когда «нормальный» человек спрашивал, как работает та или иная функция. Как будто код настолько мудрёный, что без 20-летнего стажа программирования его не понять.
Не надо так.
Лучший ответ: «Если немножко упростить, то сначала делаем X, затем делаем Y и, наконец, делаем Z, однако нужно иметь в виду десяток пограничных ситуаций (возможно, объясните одну или две), но суть такая». Ваши коллеги умны и без техножаргона вполне способны вас понять.
Ещё один действительно полезный приём — использовать непрограммиста в качестве деки, вроде резиновой утки. Если работаете над сложной проблемой, объясните ему простыми словами свой вариант решения и спросите, можно ли придумать вариант получше.
Наша компания работает в области ЧПУ, то есть имеет некоторое отношение к реальному миру (например, когда вы пытаетесь реализовать компенсацию ширины разреза). Инженеры действительно хороши в анализе проблем, связанных с физикой и геометрией.
Люди — существа социальные. Мы запрограммированы на понимание взаимоотношений и любим аналогии, чтобы соотнести новые понятия с уже известными. Когда разговариваете с кем-то, можно воспользоваться этими приёмами, чтобы довести до понимания сложные темы.
Скажем, в вашей компании работает система онлайн-закупок. Маркетолог хочет понять всю цепочку от онлайн-заказа до доставки посылки, чтобы лучше отвечать на вопросы клиентов. Я мог бы сказать что-то вроде этого:
Всё это звучит немного комично, и пример более чем надуман, но я могу гарантировать, что это более понятное объяснение, чем большая сетевая диаграмма с терминами «веб-сервер», «событийная архитектура» и «Apache Kafka» (см. раздел о технолепете).
Другой пример. Если вы пытаетесь объяснить постороннему человеку, как работает алгоритм поиска пути, вы не говорите «посещённым путям присваивается больший вес», вы говорите «алгоритм действительно не хочет идти по тем путям, где уже ходил».
Это тонкая разница, но мы выполняем персонификацию алгоритма. Мы говорим, что он «действительно хочет сделать X» или «очень стараться избегать Y». Зачастую это помогает людям просто понять.
Полезны и аналогии с примерами (если они уместны). Вероятно, вы уже заметили, что эта статья полна примеров. Вместо абстрактного объяснения я рассказываю конкретные истории, которые помогают объяснить тезис. Это не случайность.
Звучит банально, но иногда картинка действительно стоит тысячи слов.
Пару месяцев назад я читал курс на радио, а девушка рядом никак не могла запомнить, какие кнопки нажимать в меню этого маленького ЖК-дисплея 16×2.
Я спросил, может ей нарисовать схему.
Она думала, что я умник и насмехаюсь над ней.
А я не шутил.
Вместо этого я нашёл клочок бумаги, и мы вместе составили что-то вроде такого:
Программист сразу распознает диаграмму состояний из теории автоматов. Незаметно для девушки я ввёл в её мозг фундаментальную технику информатики и то, как под капотом запрограммирован интерфейс этого радио.
Но ей (и всем остальным на этом этапе) наплевать на науку. Они получили карту, которую могут использовать для навигации по пользовательскому интерфейсу.
Есть какое-то странное удовольствие в том, чтобы адаптировать сложную концепцию для кого-то из другой области. Особенно когда они могут определить, что в карте действительно баг: нужно нажать и удерживать кнопку «Отмена» (Cancel), чтобы вернуться в состояние ожидания (Idle), потому что обычное нажатие этой кнопки возвращает вас в «Главное меню».
У меня на столе всегда лежит большой блокнот с чистыми листами. Обычно я записываю туда список дел или какие-то рисунки во время размышлений, но часто он помогает в объяснениях. Возможность что-то нарисовать во время разговора помогает сверить курс и убедиться, что вы на одной волне (каламбур), что вы одинаково представляете понятия.
Допустим, вы произвели некие настройки производительности, и теперь определённый фрагмент кода работает гораздо быстрее. Как объяснить это непрограммисту или тому, кто не видит исходный код?
С одной стороны, на вопрос, чем вы занимались на прошлой неделе, можете сказать человеку правду: «Я добавил кэширование в
Вы также можете сказать, что «оптимизировали производительность», но это звучит как отмазка, а менеджер задумается, зачем взял вас на работу.
Часто разработчики говорят: «Я ускорил $FEATURE в десять раз» (или какое-то другое произвольное число) и этим ограничиваются. Такая фраза позволяет насладиться кучей поздравлений от обывателей, но зачастую она немного… вводит в заблуждение.
В большинстве случаев на самом деле вы улучшили производительность нескольких функций, но если эти функции не были узким местом в производительности, то с большой вероятностью никто не увидит никакой разницы.
Напрашивается также вопрос: что вы сделали, чтобы повысить производительность в десять раз? Это на удивление конкретное число, ваш исходный код несколько раз повторял одну работу? Или он запрашивал данные (скажем, с аппаратного обеспечения или какого-то стороннего сайта) в десять раз медленнее, чем следовало? Даже это заставляет меня сомневаться в ваших способностях, потому что вы либо угадали (плохо) исходную скорость опроса, либо все ещё жертвуете производительностью, используя опрос вместо более эффективной событийной архитектуры.
Мне кажется, что лучше попытаться найти золотую середину между точностью и понятностью. Если вы сделали изменение, которое улучшает алгоритмическую сложность фрагмента кода (например, функция
…и продолжить примерно так: «…но если дадите мне пять минут, я смогу вам сказать».
Я часто такое вижу. Люди боятся показать своё невежество, поэтому молчат, мучаются или что-то выдумывают.
Например, если к вам пришёл менеджер и спрашивает: «Клиент попросил функцию X, это возможно? И сколько времени займёт?»
В девяти случаях из десяти честный ответ: «Я не знаю», но он не очень поможет менеджеру определиться со сроками. Он обратился к вам, потому что вы являетесь экспертом в соответствующей области и лучше всего подготовлены, чтобы дать ответ.
Некоторые пытаются угадать или обманывают (например, «Да, сделаем за две-три недели»), но такой подход обычно не работает в долгосрочной перспективе. В лучшем случае вы задержитесь на пару недель, а в худшем случае потратите месяцы на работу только для того, чтобы обнаружить невозможность работы этой функции с текущей архитектурой приложения.
Это отличный способ потерять уважение коллег и начальства.
С другой стороны, слова «Не уверен, но дайте 5-10 минут, и у меня будет ответ» показывает сразу несколько вещей:
(И ты получаешь достаточно времени, чтобы всё выяснить).
Это напоминает старую притчу:
Кто угодно может загуглить любой вопрос. Но только инженер-программист знает, какие использовать ключевые слова и как интерпретировать результаты.
Обычно в своём блоге я публикую чисто технические статьи с тоннами кода, но иногда полезно помнить, что в этом мире есть что-то ещё, кроме кода.
Программистов (не без оснований) воспринимают как людей со слабыми социальными и коммуникативными навыками. Но значительная часть нашей работы требует эффективного общения. Надеюсь, мой опыт вам чем-то поможет.
Некоторые могут посчитать, что это «офисная политика» и манипулирование чужим мнением. Вот что я отвечу:
Я пишу программное обеспечение достаточно давно, чтобы столкнуться с каждой из этих проблем. В то же время я выступаю со стороны бизнеса и объясняю клиентам техническую часть нашего продукта, поэтому постоянно сталкиваюсь с непрограммистами. Самое важное — правильно передать идею или концепцию таким образом, чтобы другие её поняли.
А это очень трудно.
Как и во всех профессиональных сферах, программисты разработали собственный жаргон для быстрой передачи концепций.
Технолепет
Жаргон очень важен. Если мы с коллегой выбираем алгоритм для решения конкретной задачи, то можем сказать, что «первый вариант
O(n^2)
с минимальным оверхедом со старта, а второй амортизируется до O(n log n)
, но с дорогой установкой и настройкой».Это единственное предложение многое говорит, для каких сценариев следует использовать алгоритм и как они реализуются под капотом:
- Вариант А отлично подходит для системы с небольшим количеством входных данных.
- Вариант Б отлично подходит для работы с действительно большим количеством входных данных, где большие затраты на установку и настройку системы будут компенсированы лучшей производительностью в процессе работы.
- Если собираетесь использовать алгоритм в цикле, следует выбрать первый вариант, чтобы избежать дорогостоящего кода установки и настройки.
- Возможно, мы сможем снизить стоимость установки варианта Б с помощью кэширования.
- Вероятно, в варианте А каждый элемент входных данных сравнивается со всеми остальными (например,
for x in inputs { for y in inputs { if some_condition(x, y) { ... }}}
).
- Вероятно, вариант Б сначала создаёт дерево, затем выполняет линейный поиск с последующим поиском в этом дереве.
Как видите, мы смогли передать несколько абзацев информации в одном предложении, просто используя правильные термины.
В данном случае я имел в виду алгоритмы для обнаружения столкновений, то есть пересечений между собой двух или больше объектов. Первый проверяет все возможные комбинации входных данных, в то время как второй использует дерево квадрантов или двоичное разбиение пространства, чтобы проверять только близкие элементы.
Но если у вас встреча с людьми из-за пределов мира программирования (например, инженеры-механики или электрики, менеджеры, маркетологи), этот технический жаргон только оскорбит и запутает людей, не передавая почти никакой ценной информации.
Это то, что я называю технолепетом, бормотанием программиста.
Скажу прямо, обычно эти детали и термины не нужны людям из других областей, и им действительно всё равно.
Например, вы объясняете удивительную новую функцию, которая находит кратчайший путь от A до Б, генерируя навигационную сетку и применяя поиск A*.
Ни в коем случае не нужно описывать новую функцию как в предыдущем предложении. Вместо этого скажите что-то вроде такого: «Мы вычисляем кучу возможных путей, а затем применяем умные алгоритмы, которые используются в игровой индустрии, чтобы найти лучший маршрут».
Не имеет значения, что мы здесь используем именно поиск A* (в отличие от алгоритма Дейкстры или поиска по ширине). Неважно, что в играх поиск A* используется не только для перемещения персонажей. Собеседнику достаточно знать, что вы можете найти хороший путь от А до Б и что мы используем надёжные инструменты, уже проверенные в других областях.
Не мешает показать иллюстрацию, что вы имеете в виду…
Мне случалось наблюдать, как более опытные программисты используют техножаргон для демонстрации превосходства, чтобы показать свой невероятный интеллект и установить доминирование. Это действительно раздражает.
Не поймите неправильно, иногда бывают ситуации, когда достаточно компетентный собеседник спрашивает: «Это очень сложно, почему просто не сделать X?» — и вам придётся показать, что вы здесь эксперт, а он не знает, о чём говорит… но всё равно это можно сделать разными способами.
Не пытайтесь использовать технолепет для удовлетворения своего эго, он подвергает людей остракизму и позорит нашу профессию.
Относитесь с уважением
Так мы плавно переходим к следующему пункту… не забывайте об уважении.
Многие люди, с которыми я работаю, действительно умны и эксперты в своих областях, но необязательно у них хватает знаний и опыта в создании информационных систем.
Объясняя сложную проблему, зачастую лучше упростить понятия. Но старайтесь не быть снисходительным.
Тот инженер-программист, о котором я упоминал, часто отвечал: «Это… сложно», когда «нормальный» человек спрашивал, как работает та или иная функция. Как будто код настолько мудрёный, что без 20-летнего стажа программирования его не понять.
Не надо так.
Лучший ответ: «Если немножко упростить, то сначала делаем X, затем делаем Y и, наконец, делаем Z, однако нужно иметь в виду десяток пограничных ситуаций (возможно, объясните одну или две), но суть такая». Ваши коллеги умны и без техножаргона вполне способны вас понять.
Ещё один действительно полезный приём — использовать непрограммиста в качестве деки, вроде резиновой утки. Если работаете над сложной проблемой, объясните ему простыми словами свой вариант решения и спросите, можно ли придумать вариант получше.
Наша компания работает в области ЧПУ, то есть имеет некоторое отношение к реальному миру (например, когда вы пытаетесь реализовать компенсацию ширины разреза). Инженеры действительно хороши в анализе проблем, связанных с физикой и геометрией.
Персонификация, преувеличения и аналогии
Люди — существа социальные. Мы запрограммированы на понимание взаимоотношений и любим аналогии, чтобы соотнести новые понятия с уже известными. Когда разговариваете с кем-то, можно воспользоваться этими приёмами, чтобы довести до понимания сложные темы.
Скажем, в вашей компании работает система онлайн-закупок. Маркетолог хочет понять всю цепочку от онлайн-заказа до доставки посылки, чтобы лучше отвечать на вопросы клиентов. Я мог бы сказать что-то вроде этого:
Представьте, что клиент по имени Чарли хочет купить дюжину спиннеров. Он заходит на www.example.com, добавляет спиннеры в корзину и нажимает «Купить» (большинство людей уже знакомы с интернет-магазинами, так что можно не объяснять механизм корзины и расчёта).
Теперь компьютер Чарли отправляет заказ Сэму (веб-серверу). Тот проверяет, что у Дебби (БД) достаточно запасов для выполнения заказа. Как только Дебби даёт согласие, Сэм сообщает Чарли, что покупка успешна, и выдаёт квитанцию (возможно, отправляет счёт по электронной почте).
На заднем дворе ждёт ещё один парень (назовём его Фредом), который постоянно спрашивает Дебби, нет ли новых заказов. Если есть, то Фред сообщает реальному человеку, чтобы он взял товар с полки и передал Мэри в почтовое отделение (Мэри — тоже реальный человек, компьютеры не умеют носить спиннеры), а она отправит товар обычной почтой.
Сэм и Ребекка (движок рекомендаций) находятся в сговоре. Поэтому Сэм сообщает Ребекке о каждом заказе, чтобы она могла использовать искусственный интеллект и чёрную магию, предлагая Чарли рекомендации других продуктов.
Всё это звучит немного комично, и пример более чем надуман, но я могу гарантировать, что это более понятное объяснение, чем большая сетевая диаграмма с терминами «веб-сервер», «событийная архитектура» и «Apache Kafka» (см. раздел о технолепете).
Другой пример. Если вы пытаетесь объяснить постороннему человеку, как работает алгоритм поиска пути, вы не говорите «посещённым путям присваивается больший вес», вы говорите «алгоритм действительно не хочет идти по тем путям, где уже ходил».
Это тонкая разница, но мы выполняем персонификацию алгоритма. Мы говорим, что он «действительно хочет сделать X» или «очень стараться избегать Y». Зачастую это помогает людям просто понять.
Полезны и аналогии с примерами (если они уместны). Вероятно, вы уже заметили, что эта статья полна примеров. Вместо абстрактного объяснения я рассказываю конкретные истории, которые помогают объяснить тезис. Это не случайность.
Рисуйте красивые картинки
Звучит банально, но иногда картинка действительно стоит тысячи слов.
Пару месяцев назад я читал курс на радио, а девушка рядом никак не могла запомнить, какие кнопки нажимать в меню этого маленького ЖК-дисплея 16×2.
Я спросил, может ей нарисовать схему.
Она думала, что я умник и насмехаюсь над ней.
А я не шутил.
Вместо этого я нашёл клочок бумаги, и мы вместе составили что-то вроде такого:
Программист сразу распознает диаграмму состояний из теории автоматов. Незаметно для девушки я ввёл в её мозг фундаментальную технику информатики и то, как под капотом запрограммирован интерфейс этого радио.
Но ей (и всем остальным на этом этапе) наплевать на науку. Они получили карту, которую могут использовать для навигации по пользовательскому интерфейсу.
Есть какое-то странное удовольствие в том, чтобы адаптировать сложную концепцию для кого-то из другой области. Особенно когда они могут определить, что в карте действительно баг: нужно нажать и удерживать кнопку «Отмена» (Cancel), чтобы вернуться в состояние ожидания (Idle), потому что обычное нажатие этой кнопки возвращает вас в «Главное меню».
У меня на столе всегда лежит большой блокнот с чистыми листами. Обычно я записываю туда список дел или какие-то рисунки во время размышлений, но часто он помогает в объяснениях. Возможность что-то нарисовать во время разговора помогает сверить курс и убедиться, что вы на одной волне (каламбур), что вы одинаково представляете понятия.
Я ускорил $FEATURE в десять раз
Допустим, вы произвели некие настройки производительности, и теперь определённый фрагмент кода работает гораздо быстрее. Как объяснить это непрограммисту или тому, кто не видит исходный код?
С одной стороны, на вопрос, чем вы занимались на прошлой неделе, можете сказать человеку правду: «Я добавил кэширование в
lookup_something ()
, чтобы ускорить общий поиск и перевести алгоритм в detect_collisions()
с O(n^2)
на O(n log n)
», но с высокой вероятностью они ничего не поймут (см. технолепет).Вы также можете сказать, что «оптимизировали производительность», но это звучит как отмазка, а менеджер задумается, зачем взял вас на работу.
Часто разработчики говорят: «Я ускорил $FEATURE в десять раз» (или какое-то другое произвольное число) и этим ограничиваются. Такая фраза позволяет насладиться кучей поздравлений от обывателей, но зачастую она немного… вводит в заблуждение.
В большинстве случаев на самом деле вы улучшили производительность нескольких функций, но если эти функции не были узким местом в производительности, то с большой вероятностью никто не увидит никакой разницы.
Примечание. Если вы знакомы с законом Амдала, то повышение производительности функции, которая не является узким местом, похоже на использование большего количества ядер CPU для задачи, которая по своей сути является последовательной.
Напрашивается также вопрос: что вы сделали, чтобы повысить производительность в десять раз? Это на удивление конкретное число, ваш исходный код несколько раз повторял одну работу? Или он запрашивал данные (скажем, с аппаратного обеспечения или какого-то стороннего сайта) в десять раз медленнее, чем следовало? Даже это заставляет меня сомневаться в ваших способностях, потому что вы либо угадали (плохо) исходную скорость опроса, либо все ещё жертвуете производительностью, используя опрос вместо более эффективной событийной архитектуры.
Мне кажется, что лучше попытаться найти золотую середину между точностью и понятностью. Если вы сделали изменение, которое улучшает алгоритмическую сложность фрагмента кода (например, функция
detect_collisions()
перешла с O(n^2)
на O(n log n)
), то можете сказать: «Функция X теперь может масштабироваться на большой объём входных данных за разумное время, а раньше не могла».Вполне нормально сказать «Не знаю»...
…и продолжить примерно так: «…но если дадите мне пять минут, я смогу вам сказать».
Я часто такое вижу. Люди боятся показать своё невежество, поэтому молчат, мучаются или что-то выдумывают.
Например, если к вам пришёл менеджер и спрашивает: «Клиент попросил функцию X, это возможно? И сколько времени займёт?»
В девяти случаях из десяти честный ответ: «Я не знаю», но он не очень поможет менеджеру определиться со сроками. Он обратился к вам, потому что вы являетесь экспертом в соответствующей области и лучше всего подготовлены, чтобы дать ответ.
Некоторые пытаются угадать или обманывают (например, «Да, сделаем за две-три недели»), но такой подход обычно не работает в долгосрочной перспективе. В лучшем случае вы задержитесь на пару недель, а в худшем случае потратите месяцы на работу только для того, чтобы обнаружить невозможность работы этой функции с текущей архитектурой приложения.
Это отличный способ потерять уважение коллег и начальства.
С другой стороны, слова «Не уверен, но дайте 5-10 минут, и у меня будет ответ» показывает сразу несколько вещей:
- Ты готов признать, что не знаешь всего (то есть не самовлюблённый эгоист).
- Ты отвечаешь за свои слова и не хочешь давать неточный ответ.
- Ты достаточно уважаешь человека, чтобы потратить часть своего времени, помогая ответить на его вопрос.
- Ты хороший парень :).
(И ты получаешь достаточно времени, чтобы всё выяснить).
Это напоминает старую притчу:
Другие люди (обычно) не ожидают, что вы знаете всё в своей области. Вместо этого они ожидают, что у вас есть инструменты для исследования вопроса и перевода ответа в термины, которые они смогут понять.
Старый инженер ушёл на пенсию, а через несколько недель сломалась Большая Машина, очень важная для доходов компании. Менеджер не смог заставить машину снова работать, поэтому компания пригласила старого инженера в качестве независимого консультанта.
Он согласился. Придя на фабрику, он посмотрел на Большую Машину, взял кувалду и ударил по ней один раз. После этого машина заработала. Старый инженер ушёл, а компания снова начала зарабатывать деньги.
На следующий день менеджер получает от старого инженера счёт на 5000 долларов. Менеджер в ярости и отказывается платить. Старый инженер уверяет, что это справедливая цена. Менеджер парирует, что если это справедливая цена, то можно попросить детализацию счёта.
Новый, детализированный счёт выглядит так…
Молоток: $5
Знать, в каком месте машины ударить молотком: $4995
Кто угодно может загуглить любой вопрос. Но только инженер-программист знает, какие использовать ключевые слова и как интерпретировать результаты.
Выводы
Обычно в своём блоге я публикую чисто технические статьи с тоннами кода, но иногда полезно помнить, что в этом мире есть что-то ещё, кроме кода.
Программистов (не без оснований) воспринимают как людей со слабыми социальными и коммуникативными навыками. Но значительная часть нашей работы требует эффективного общения. Надеюсь, мой опыт вам чем-то поможет.
Некоторые могут посчитать, что это «офисная политика» и манипулирование чужим мнением. Вот что я отвечу:
Ну… да. А разве это не относится к большинству межличностных взаимодействий?
Психология просто помогает программистам разговаривать с непрограммистами на одном языке и работать вместе для достижения общей цели.