Большинство гайдов по программному обеспечению написаны трагически плохо.
В них не хватает важной информации, и это мешает пользователям повторить описанные в руководстве процессы. Иногда автор исходит из скрытых предпосылок, которые не соответствуют ожиданиям читателя.
Но есть и хорошая новость: научиться писать грамотные руководства проще, чем вы думаете. Следуйте нескольким простым правилам, и ваши тексты будут выделяться на фоне повсеместной посредственности.
Правила
Пишите для чайников
Самая распространённая ошибка гайдов — когда объяснение адресовано новичкам, а написано сложным экспертным языком.
![Мастер-класс для начинающихНе пойму, почему никто не хочет попробовать скалолазание? Мастер-класс для начинающихНе пойму, почему никто не хочет попробовать скалолазание?](https://habrastorage.org/getpro/habr/upload_files/bd8/941/5b7/bd89415b734ea2fd70bea6705ab97d85.png)
Не пойму, почему никто не хочет попробовать скалолазание?
Руководства чаще всего читают начинающие. Или программисты с опытом, изучающие новое для них направление.
|
В этом руководстве я расскажу, как создать первый SPA «Hello world» на React. Откройте приложенный файл Для отображения нового текста браузер не перезагружается. За счёт эффективной транспиляции JSX в React изменения видны сразу же. Браузеру даже не нужна мягкая перезагрузка, потому что механизм сверки React сравнивает виртуальный и текущий DOM и обновляет только те элементы DOM, которым требуются изменения. |
Приведённый выше пример отпугнёт новичков.
Разработчик, который ещё не работал с веб-фреймворком React, не понимает, что такое транспиляция JSX или механизм сверки. А если он не работал с другими фреймворками JavaScript, ему также будут незнакомы SPA, мягкая перезагрузка и виртуальный DOM.
Когда вы пишете гайд, помните: вы обращаетесь не к экспертам. Избегайте профессионального жаргона, сокращений или терминов, которые ничего не значат для новичка.
Это введение в руководство по React написано языком, который будет понятен читателям, даже если у них нет опыта в программировании.
|
В этом руководстве я покажу вам, как создать простую веб-страницу с помощью современных инструментов веб-разработки. Для этого я использую React, бесплатный популярный инструмент для создания сайтов. React отлично подойдёт для первого в вашей жизни сайта. В то же время это мощное полнофункциональное решение для создания сложных приложений, которыми пользуются миллионы людей во всём мире. |
Если вы пишете для новичков, это вовсе не значит, что вы оттолкнёте опытных пользователей. Компетентный читатель может бегло просмотреть руководство и пропустить разделы, с которыми уже знаком. Но новичок не сможет прочитать гайд для экспертов.
Пообещайте в заголовке чёткий результат
Если читатели ищут ответ в Google, подскажет ли им заголовок вашей статьи искомое решение? Если они увидят ваше руководство в соцсетях или в рассылке, убедит ли их заголовок перейти по ссылке?
-
Полное руководство о том, как стать гуру в CSV на Python
-
Как создать свой собственный Twitter
Key Mime Pi: сделайте классный гаджет
Как создать компилятор
Вот примеры слабых заголовков:
|
• Полное руководство о том, как стать гуру в CSV на Python |
Это слабые заголовки, потому что они не поясняют, о чём текст. Из такого заголовка неясно, чему научит руководство. Заголовок должен лаконично объяснять, чего читатель может ожидать, ознакомившись с руководством. Вот как можно переписать предыдущие заголовки:
|
• Как читать CSV-файл в Python |
Из этих заголовков совершенно ясно, чему научится читатель, ознакомившись с руководством.
Во введении объясните цель статьи
Если читатель открыл ваш гайд, это уже отличный старт: кому-то интересно, о чём вы пишете. Но вам всё ещё нужно убедить его, что стоит читать руководство дальше.
В начале руководства читатель стремится максимально быстро найти ответ на два важных вопроса:
-
Надо ли изучать эту технологию?
-
А если надо, подходящее ли руководство я открыл?
Первые предложения статьи должны дать ответы на эти вопросы.
Вот просто ужасное введение в статью о том, как использовать контейнеры Docker.
|
Введение в контейнеры Docker Docker — чрезвычайно мощная и универсальная технология. Она позволяет запускать приложение в контейнере, то есть отдельно от всех остальных элементов системы. В этом руководстве я покажу вам, как с помощью Docker запускать контейнеры в локальной инфраструктуре и в облаке. |
Если судить по этому введению, какую проблему решает Docker? Кому стоит им пользоваться?
Во введении нет ответа на эти вопросы. Зато есть приветственные помахивания с туманными терминами и игнорирование моментов, актуальных для читателя.
Ниже формулировка, в которой объясняется, как Docker устраняет боли читателя:
|
Как использовать Docker для надёжного деплоймента приложений Боитесь трогать свой продакшн-сервер, потому что никто не знает, как наладить его работу после сбоя? Рвёте на себе волосы, потому что не понимаете, почему промежуточная рабочая среда работает не так, как продакшн-среда? Docker помогает упаковать приложение так, чтобы оно всегда выполнялось в единообразной воспроизводимой среде. С помощью Docker можно задать среду приложения и его зависимости в исходном коде, так что вы будете точно знать, что к чему, даже если ваше приложение годами отлаживали разные команды. В этом руководстве я покажу вам, как использовать Docker для упаковки простого веб-приложения и не допустить распространённых ошибок. |
В этом введении говорится, какие проблемы можно устранить с помощью Docker и какую конкретно задачу помогает решить гайд.
Во введении не сказано: «Это руководство для тех, кто ничего не знает про Docker». Но это и не нужно. В нём Docker описывается как новая концепция, так что всем понятно, что гайд для новичков.
Покажите конечный результат
Как можно скорее покажите на демо или скриншоте, что читатель сможет создать к концу гайда.
Не то чтобы этот конечный результат должен поражать воображение. Вот как я показал UI терминала, который пользователь увидит в конце руководства:
![В начале гайда покажите читателю превью результата, который они получат после чтения статьи В начале гайда покажите читателю превью результата, который они получат после чтения статьи](https://habrastorage.org/getpro/habr/upload_files/e96/46b/690/e9646b690988ce4c32d0ae559cc93f0f.png)
Такой конечный результат повышает определённость решаемой задачи. Так читателю проще понять, подходит ли ему ваш гайд.
Разрешите копировать сниппеты кода
Когда читатель будет выполнять пункт за пунктом гайда, ему в какой-то момент понадобится скопировать сниппеты кода в редактор или терминал.
Удивительно, сколько гайдов не разрешают копирование. А ведь без этого читателю гораздо труднее проверить в деле примеры из статьи.
Разрешите копировать команды оболочки
Очень распространённая ошибка, связанная со сниппетами кода, — использование символа shell prompt.
Сниппет оболочки с символом $ не будет работать, когда пользователь попытается скопировать его в терминал.
$ sudo apt update # <<< Don't do this! $ sudo apt install vim # <<< Users can't copy/paste this sequence without $ vim hello.txt # << picking up the $ character and breaking the command.
Даже в Google не удаётся скопировать её без косяков. В некоторых статьях услужливо предусмотрена кнопка «Скопировать образец кода».
![В Google есть кнопка «Скопировать образец кода», но символы терминала оболочки копируются неправильно В Google есть кнопка «Скопировать образец кода», но символы терминала оболочки копируются неправильно](https://habrastorage.org/getpro/habr/upload_files/e2c/385/695/e2c385695a4155dc5e89d2619fd8fefb.png)
Если нажать кнопку копирования, она скопирует $, символ приглашения терминала, так что вам не удастся вставить код:
michael@ubuntu: $ gcloud services enable pubsub.googleapis.com $ gcloud services disable pubsub.googleapis.com bash: $: command not found bash: $: command not found michael@ubuntu:
Есть и другой вариант этой ошибки, не такой заметный:
|
|
Если я попытаюсь скопировать этот сниппет, вот что я увижу в терминале:
0 upgraded, 89 newly installed, 0 to remove and 2 not upgraded. Need to get 36.1 MB of archives. After this operation, 150 MB of additional disk space will be used. Do you want to continue? [Y/n] Abort. $
Что случилось?
При выполнении команды apt install software-properties-common требуется пользовательский ввод. А пользователь не может выполнить это действие, потому что apt просто считывает буфер обмена дальше.
В большинстве инструментов командной строки поддерживаются флаги или переменные среды, избавляющие пользователя от необходимости интерактивного взаимодействия. С помощью неинтерактивных флагов можно упростить копирование сниппетов команд в терминал пользователей.
|
|
Объединяйте команды оболочки с помощью &&
Давайте вернёмся к примеру установки Python, который я приводил выше. В нём есть ещё одна проблема:
|
|
Пользователи не всегда замечают, что одна из команд завершилась с ошибкой. Например, если первая команда — sudo apt cache ppa:dummy:non-existent, она завершится с ошибкой, но оболочка радостно выполнит следующую команду, как будто до этого всё было отлично.
В большинстве оболочек Linux можно объединять команды с помощью && и продолжать строки обратным слешем. В этом случае оболочка прерывает работу, если команда завершается с ошибкой.
Вот удобный способ представить последовательность копируемых команд:
|
|
Так пользователь может копировать и вставлять всю последовательность: ему не придётся возиться с промежуточными этапами. Если в какой-то команде возникает ошибка, вся последовательность сразу же останавливается.
Показывайте shell prompt, только чтобы продемонстрировать результат
Иногда символ shell prompt можно использовать для пользы читателя.
Если вы показываете команду и результат её выполнения, символ shell prompt помогает читателю различать, что он вводит и что получается в результате.
Например, в руководстве об утилите jq можно представить результаты следующим образом:
|
Утилита jq позволяет элегантно реструктурировать данные JSON:
|
Исключите номера строк из копируемого текста
Указывать номера строк в сниппетах кода — это нормально. Но убедитесь, что они не мешают корректно копировать код. Например, если пользователь пытается скопировать функцию count_tables из следующего сниппета, ему придётся удалять номера строк из копируемого текста.
|
|
Используйте длинные варианты флагов командной строки
В утилитах командной строки часто предусмотрено два варианта одного и того же флага: короткий и длинный.
-r / --recursive : Run recursively ^ ^ | | | long flag | short flag
Всегда используйте длинные флаги в гайдах. Они более содержательные, так что новичкам будет проще читать такой код.
|
Запустите эту команду, чтобы найти все страницы с элементами
|
Даже если читатель знаком с инструментом grep, скорее всего, он не помнит наизусть все его флаги.
Используйте длинные флаги, чтобы примеры были понятны и опытным пользователям, и новичкам.
|
Запустите эту команду, чтобы найти все страницы с элементами <span>:
|
Разделяйте пользовательские значения и переиспользуемую логику
Пример кода часто содержит как элементы, присущие решению, так и элементы, которые каждый пользователь может настроить на своё усмотрение. Объясните читателю, что есть что.
Возможно, вам различия между пользовательским значением и остальным кодом очевидны, но они непонятны человеку, который только вникает в тему.
Используйте переменные среды в примерах командной строки
Сервис логирования, которым я пользуюсь, приводит следующий пример кода для извлечения логов в командной строке.
|
|
Какие значения заменять в этом примере?
Очевидно, нужно заменить плейсхолдер YOUR-API-TOKEN. А как насчёт YYYY-MM-DD? Вставлять ли на его месте реальные даты вроде 2024-11-23? Или он указывает на схему даты, в том смысле, что YYYY-MM-DD — это буквенное значение, которое надо оставить как есть?
В этом примере есть ещё несколько чисел и строк. А их заменять надо?
Не заставляйте пользователя гадать, какие значения в вашем примере нужно менять. Просто укажите чёткие отличия одного от другого. Начните с редактируемых значений, потом приведите сниппет, который читатели могут скопировать без изменений.
Вот как я переписал пример выше:
|
|
В новом варианте указаны значения, которые нужно заменить, и код, который остаётся без изменений.
Использование переменных среды проясняет назначение пользовательских значений. Благодаря этому пользователю придётся вводить каждое уникальное значение только один раз.
Используйте именованные константы в исходном коде
Представьте, что вы пишете руководство о том, как обрезать изображение, чтобы оно по формату подходило для постов в Bluesky и Х (ранее Twitter):
![Изображение в статье имеет размеры, подходящие именно для картинки для поста Изображение в статье имеет размеры, подходящие именно для картинки для поста](https://habrastorage.org/getpro/habr/upload_files/2d8/83d/58e/2d883d58ec724d89dcad786f482e8d50.png)
Вот как можно показать код для обрезки рисунка под размер картинки для поста.
|
|
В примере четыре числа:
-
800;
-
1,91;
-
2;
-
2 (ещё раз).
Какие числа можно спокойно менять?
В примерах исходного кода чётко указывайте, какие значения — неотъемлемая часть решения, а какие — произвольные.
Поменяем формулировки, чтобы прояснить назначение чисел.
|
|
В этом примере значение 1.91 становится именованной константой, а код содержит комментарий, в котором объясняется, что это за цифра. Таким образом, читатель понимает, что значение не надо менять, поскольку в этом случае у изображения будут пропорции, не подходящие для картинки для поста.
С другой стороны, ширину можно поменять, и из комментария читателю становится ясно, что вместо 800 можно указать другую цифру.
Не загружайте читателя бессмысленными задачами
Читатель по достоинству оценит гайд, который экономит его время.
Не перегружайте пользователя утомительными итерациями, когда в результате выполнения сниппета командной строки получается один и тот же результат.
|
Выполните следующие утомительные действия: 1. Запустите |
Из-за таких пунктов руководство становится скучным, а пользователь легко может допустить ошибку. Кто захочет раз за разом вручную редактировать текстовый файл?
Лучше покажите читателю сниппет командной строки, который делает то, что ему нужно.
|
Вставьте следующую простую команду:
|
Поддерживайте код в рабочем состоянии
Некоторые авторы готовят руководства, как будто это инструкции по складыванию оригами: эдакая таинственная последовательность поворотов и изгибов. Пока не доберёшься до конца, эта свёрнутая бумажка не вызывает никаких ассоциаций, и вдруг — о чудо, вот он, прекрасный лебедь!
Возможно, любители оригами ценят непредсказуемость, но читателя такой процесс нервирует.
Он хочет знать, что всё делает правильно. А для этого код должен быть в рабочем состоянии.
|
Вот код для примера. Но вы не занимайтесь его компиляцией. В нём не хватает функции
|
Если читатель пытается скомпилировать пример выше, возникает ошибка:
$ gcc example.c -o example example.c: In function ‘main’: example.c:14:7: warning: implicit declaration of function ‘parseOption’ [-Wimplicit-function-declaration] 14 | parseOption(line, key, value); // <<< Not yet defined | ^~~~~~~~~~~ /usr/bin/ld: /tmp/ccmLGENX.o: in function `main': example.c:(.text+0x2e): undefined reference to `parseOption' collect2: error: ld returned 1 exit status
Как можно раньше покажите читателю пример, с которым он может работать. Опирайтесь на этот постулат и поддерживайте код в рабочем состоянии.
|
Теперь я протестирую программу, чтобы убедиться, что она работает:
Пока что в коде используются выдуманные параметры парсинга, но фиктивный код подтверждает, что всё остальное работает. |
Если код работает, пользователь понимает, правильно ли он выполняет рекомендации из статьи. Ему не нужно беспокоиться, не допустил ли он несущественную ошибку, из-за которой позднее придётся всё перепроверять.
Посвятите гайд одной теме
Хорошее руководство должно объяснять только одну вещь — и объяснять её хорошо.
Распространённая ошибка — заявить конкретную тему гайда, а потом смешать коктейль из разных технологий.
|
В этом руководстве я покажу вам, как добавить в блог Hugo поиск на стороне клиента, чтобы ваши читатели могли мгновенно выполнять полнотекстовый поиск по всем статьям блога даже при слабом мобильном интернете. Но это ещё не всё! Помимо полнотекстового поиска, я покажу вам, как использовать локальное хранилище браузера для хранения истории пользовательского поиска и как применить дорогой ИИ-сервис для выводов о том, какая тема больше нравится пользователям вашего сайта: тёмная или светлая. |
В приведённом примере руководство сначала обещает нечто полезное для множества читателей: полнотекстовый поиск по блогу.
Сразу вслед за ним в сборную солянку попадают не связанные друг с другом идеи. Теперь читатель, которому нужен полнотекстовый поиск, должен вычленить интересующую его тему из статьи.
Люди открывают гайд, потому что их интересует один конкретный вопрос. Предоставьте им возможность получить на него ответ, и всё.
|
В этом руководстве я покажу вам, как добавить в блог Hugo поиск на стороне клиента, чтобы ваши читатели могли мгновенно выполнять полнотекстовый поиск по всем статьям блога даже при слабом мобильном интернете. В этом гайде я остановлюсь только на этом вопросе. |
Если вам нужно сформировать стек технологий, подождите до конца гайда
Иногда в руководстве приходится сочетать несколько технологий.
Например, у языка веб-программирования PHP нет встроенного рабочего веб-сервера. Чтобы показать, как задеплоить PHP-приложение в веб, вам придётся выбрать какой-то сервер, например: Apache, nginx или Microsoft IIS. Какой бы вариант вы ни выбрали, это оттолкнёт пользователей, которые предпочитают другой сервер.
Если вам нужно объединить несколько технологий, отложите это на конец гайда. Если пишете о PHP, постарайтесь как можно дольше продержаться на сервере разработки PHP. Если вы показываете, как задеплоить PHP-приложение в продакшн-среде на nginx, перенесите эти этапы на конец статьи. Тогда все, кто работает с другими серверами, смогут пройтись по этапам руководства до момента, когда вы дойдёте до раздела про серверы.
Не приукрашивайте
Вот отрывок из статьи, которую я недавно прочитал. Можете догадаться, что это был за гайд?
|
|
Думаете, это статья о фреймворке CSS? А вот и нет.
Этот сниппет — из руководства об использовании элемента <slot> в веб-фреймворке Vue. Так почему же половина кода приходится на классы CSS? Автор добавил их, чтобы пример смотрелся привлекательнее.
Вот тот же сниппет, в котором мы оставим только код, необходимый для объяснения главного понятия:
|
|
Да, из этого упрощённого кода не получится красивая картинка, которая хорошо смотрится в браузере. Но это и не нужно. Зато таким образом можно доходчиво рассказать об элементе <slot>, не отвлекая читателя на посторонние моменты.
Читателям неважно, красиво ли смотрится приложение, которое вы приводите для примера. Им нужен гайд, который однозначно объясняет новое понятие.
Сократите зависимости по максимуму
В каждом руководстве попадаются зависимости. Как минимум, читателю нужна операционная система. Скорее всего, для выполнения предложенных примеров ему ещё понадобится конкретный компилятор, библиотека или фреймворк.
Каждая зависимость добавляет читателю работы. Ему нужно разобраться, как установить и настроить всё это в системе, а это снижает шансы пройти руководство до конца.
Упростите руководство, максимально сократив число необходимых зависимостей.
|
Итак, мы добрались до пункта 12. Самое время установить ещё букет раздражающих вас программ, о которых я не упомянул раньше: • Ffmpeg вместе с расширением libpita (скомпилированные двоичные файлы недоступны); |
Самые распространённые и фривольные зависимости, которые я вижу, — это библиотеки для парсинга дат. Вам тоже встречались подобные инструкции?
|
CSV-файл содержит даты в формате |
На самом деле, вам совершенно не нужна целая сторонняя библиотека, чтобы спарсить простую строку данных в коде, который мы берём для примера. В худшем случае вы можете спарсить её самостоятельно пятью строчками кода.
Мало того, что со сторонними инструментами сложнее следовать инструкциям в гайде, так ещё и каждая зависимость сокращает «срок службы» руководства. Возможно, через месяц внешняя библиотека выпустит обновление, из-за которого ваш код перестанет работать. Или издатель снимет библиотеку с публикации, и тогда ваш гайд станет вообще бесполезным.
Полностью избавиться от зависимостей не удастся, но применять их нужно стратегически. Если в руководстве вы рассказываете, как изменить размер изображения, не стесняйтесь, воспользуйтесь сторонней библиотекой изображений, а не создавайте с нуля декодирование JPEG. Но если вместо зависимости можно написать 20 строк кода, почти всегда лучше обойтись без зависимости.
Зафиксируйте определённые версии зависимостей
Чётко проговаривайте, какие версии инструментов и библиотек используются у вас в руководстве. Библиотеки издают обновления без обратной совместимости, так что обязательно убедитесь, что пользователь знает, какая версия точно работает.
|
Установите стабильную версию Node.js. |
|
Установите Node.js 22.x. Я тестировал это на Node.js v22.12.0 (LTS). |
Чётко указывайте имена файлов
Больше всего меня бесит, когда автор руководства небрежно указывает: «Добавьте эту строку в файл конфигурации».
В какой именно файл конфигурации? Где именно?
|
Чтобы включить удаление неиспользуемого кода, добавьте эту настройку в файл конфигурации:
|
Если читателю нужно отредактировать файл, дайте ему полный путь к файлу и точно покажите, какую строку отредактировать.
Указать имя файла можно множеством способов: в комментариях к коду, в заголовке или даже в предыдущем абзаце. Сгодится любой метод, который однозначно показывает пользователю, где вносить изменения.
|
Чтобы включить удаление неиспользуемого кода, добавьте следующий параметр оптимизации в module.exports файла конфигурации webpack:
|
Используйте единообразные содержательные заголовки
Большинство читателей сначала бегло просматривают гайд, чтобы определить, стоит ли читать его внимательно. Такое чтение по верхам помогает читателю решить, найдёт ли он в гайде ответы на свои вопросы и трудно ли будет выполнить описанные в нём действия.
Если убрать заголовки, перед читателем расстилается сплошное полотно текста.
Заголовки же структурируют статью. Большое руководство со множеством пунктов лучше разбить на несколько разделов, в каждом из которых будет по 5–6 подпунктов.
Пишите чёткие заголовки
Недостаточно просто разделить длинное полотно текста парой заголовков.
Продумайте формулировки заголовков: не жертвуйте их лаконичностью, но постарайтесь вложить в них как можно больше содержательности.
Какие из этих руководств вы бы предпочли? Эти?
|
1. Go |
Или эти?
|
1. Чем хорош Go |
Во втором примере намного больше информации, которая помогает читателю решить, подходит ли ему этот гайд.
Сделайте заголовки единообразными
Перед публикацией гайда проверьте, точно ли у него единообразные заголовки.
|
1. Как я установил Go 1.23 |
Проверяя заголовки, обращайте внимание на следующие моменты:
-
Грамматические формы.
Ваши заголовки — это именные или глагольные предложения? -
От чьего лица ведётся повествование.
Можно писать от первого лица («Я сделал X»), обращаться к читателю как к собеседнику («Сделайте X») или выбрать нейтральную манеру. -
Грамматическое время.
Вы пишете в настоящем, прошедшем или будущем времени?
Создайте с помощью заголовков логическую структуру
Убедитесь, что заголовки отражают логическую структуру руководства.
Я часто вижу статьи, в которых заголовки смотрятся как бессмысленный набор фраз.
|
1. Почему Go |
В приведённом примере у заголовка «Почему Go» есть подзаголовок «История nginx», хотя история nginx логически не является подтемой темы про Go.
Покажите, что ваше решение работает
Если в руководстве объясняется, как установить инструмент или интегрировать несколько компонентов, покажите, как использовать результат.
|
Наконец, выполните команду, чтобы активировать сервис nginx:
Поздравляем! Готово! Я предполагаю, что вы и так знаете, как действовать дальше, так что на этом моя миссия выполнена. |
Если вы объясняете, как что-то установить, покажите читателю, как работает достигнутый результат.
Иногда это элементарное действие, например распечатать строку с версией. Просто покажите, как использовать инструмент для чего-то, чтобы читатель знал, есть ли польза от гайда.
|
Наконец, выполните команду, чтобы активировать сервис nginx:
Далее перейдите по этому URL-адресу в браузере: Если всё работает, вы увидите nginx success page по умолчанию. |
![Success page в nginx Success page в nginx](https://habrastorage.org/getpro/habr/upload_files/1c9/000/e2c/1c9000e2cb53b73ce92c0ef0536b7105.png)
В следующих разделах я покажу, как заменить веб-страницу nginx по умолчанию и выполнить настройки nginx для решения ваших задач. |
Увяжите конкретику с комплексным примером
Даже если на протяжении всего гайда вы придерживались одной темы, не помешает показать читателю, как всё работает в комплексе.
Дайте ему ссылку на репозиторий со всем кодом, который вы показывали в руководстве. В идеале репозиторий лучше устроить в системе непрерывной интеграции вроде CircleCI или GitHub Actions, чтобы было видно, что ваш пример создан в актуальной среде.
Бонус: показывайте полный код на каждом этапе
Я охотно разбиваю репозиторий на ветки Git, чтобы читатель видел не только конечный результат, но и общее состояние проекта в каждом разделе руководства.
Например, в руководстве «Как протестировать PDF-парсер с помощью Nix» я показываю читателю первую собираемую версию репозитория в собственной ветке:
В конце руководства даю ссылку на конечный результат:
Если размер файлов слишком велик, чтобы показывать их после каждого изменения, приводите ссылки на ветки, чтобы читатель видел, как компоненты руководства работают в комплексе.
Чтобы расти, нужно выйти из привычной зоны и сделать шаг к переменам. Можно изучить новое, начав с бесплатных занятий:
-
Специалист по информационной безопасности: старт карьеры;
-
Системный аналитик: первые шаги к профессии.
Или открыть перспективы и получить повышение с профессиональным обучением:
ссылка на оригинал статьи https://habr.com/ru/articles/873674/
Добавить комментарий