Автор материала, перевод которого мы публикуем, собрал 19 идей, которые могут оказаться полезными для тех Node.js-разработчиков, которые хотят повысить свой профессиональный уровень в 2019 году. Мир JavaScript огромен, поэтому освоить всё то, о чём пойдёт здесь речь, попросту нереально. Вряд ли найдётся кто-то, кто владеет всем этим в совершенстве. Однако кое-что в этом обзоре вполне может пригодиться именно вам.
19 идей для Node.js-разработчиков, которые стремятся вырасти над собой в 2019 году
1. Подумайте о типизации. Обратите внимание на TypeScript
Доказано, что программирование на JavaScript, с использованием применяемого в нём подхода к типизации, ведёт к снижению производительности труда и к появлению ошибок. Это не означает, что нужно стремиться к тому, чтобы весь код был бы строго типизированным. Скорее речь идёт о том, что хорошо было бы, при разработке на JavaScript, выбрать некий подход к работе с типами и придерживаться его. Такие подходы различаются, кроме прочего, уровнем ограничений, связанных с типами данных, накладываемых на код. Например, это может быть что-то совсем простое, нечто вроде организации проверок с использованием пакета jsonschema (или joi). Если вы чувствуете, что нуждаетесь в более строгом контроле типов — можете рассмотреть вариант использования аннотаций типов в обычном JS-коде (тут вам поможет flow от Facebook). А если вы готовы к написанию практически полностью типизированного кода — обратите внимание на TypeScript.
Надо отметить, что в 2018 году TypeScript обрёл серьёзную популярность, кроме того, возникает такое ощущение, что есть все предпосылки к тому, чтобы он прочно обосновался в среде Node.js. Если вы серьёзно посматриваете в сторону TypeScript — вы должны спросить себя о том, думаете ли вы лишь о типизации, или также о других возможностях языка. Дело тут в том, что работа с чем-то вроде интерфейсов и абстрактных классов будет означать, что вы попадёте в среду, в которую, думая преимущественно о типизации, вы вряд ли собирались попасть.
2. Обратите внимание на возможности линтеров
Линтеры в наши дни воспринимаются как нечто само собой разумеющееся. После простой настройки в вашем распоряжении оказывается инструмент, помогающий находить в коде ошибки. Прошли те времена, когда линтинг кода означал преимущественно контроль его оформления (чего-то вроде наличия или отсутствия точек с запятой). Теперь линтеры могут выявлять серьёзные проблемы — наподобие ошибок, которые не обрабатываются должным образом, промисов, которые никогда не разрешаются, и других подобных неприятностей, которые никто не станет сознательно включать в свой код. Поэтому если вы ещё не пользуетесь линтером — сейчас самое время это сделать, не забыв о его вдумчивой настройке. Вот, например, плагин для ESLint, eslint-plugin-chai-expect, который может выявлять ошибочно составленные тесты. Вот плагин eslint-plugin-promise, обнаруживающий неразрешаемые промисы (код с такими промисами, без видимых причин, попросту останавливается). С помощью плагина eslint-plugin-security можно находить в коде небезопасные регулярные выражения, которые могут быть использованы злоумышленником для проведения DOS-атак.
3. Углубите свои знания об архитектуре программных проектов, переняв кое-что из мира Java и забыв многое из мира Ruby
В экосистеме Node.js нечасто поднимается тема архитектуры и проектирования информационных систем. Так, все говорят о микросервисах, но лишь очень немногие — об их внутреннем устройстве. В результате большинство Node.js-приложений представляют собой образцы реализации концепций MVC и других сомнительных паттернов из мира Ruby. Что в этом плохого? Шаблон MVC, например, был создан для упорядочения работы с данными, а вот для проектирования надёжных серверных частей приложений этот шаблон не годится. Боб Мартин, например, говорит, что MVC — это механизм доставки данных пользователю, а не архитектура приложений. Неужели можно описать бизнес-логику микросервисного приложения, правила его работы, особенности доступа к данным, взаимодействие с другими микросервисами, используя лишь два класса — Controller
и Model
?
Надо отметить, что я совершенно не хочу рекомендовать здесь применение в Node.js шаблонов из Java/Spring (ведь мы не случайно перешли именно на Node.js для разработки серверных программ?). Я посоветовал бы позаимствовать лишь некоторые идеи, которые, с одной стороны, способны благотворно сказаться на архитектуре приложений, а с другой, не станут причиной их чрезмерного усложнения.
Вот некоторые рекомендации для тех, кого заботит архитектура Node.js-проектов:
- Почитайте первый раздел этого материала, посвящённый архитектуре Node.js-приложений.
- Постарайтесь не смешивать бизнес-логику приложений с объектами Express, почитайте о принципах предметно-ориентированного проектирования (Domain-Driven Design, DDD) и о гексагональной архитектуре.
- Применение паттерна Active Record, весьма популярного среди разработчиков, использующих Mongoose и Sequelize, легко приводит к появлению чрезмерно перегруженных возможностями объектов, которые сложно тестировать. Подумайте об использовании паттерна Data Mapper вместо паттерна Active Record.
- Ознакомьтесь с кодом этого хорошо сделанного шаблонного Node.js-проекта, отличающегося качественной архитектурой, в котором реализованы принципы DDD.
4. Подумайте о том, как использовать новое Node.js-API async_hooks при работе с асинхронным кодом
Однопоточная модель выполнения кода, используемая в JavaScript, имеет один серьёзный недостаток — асинхронные операции, например — запросы, теряют контекст. Он не сохраняется в течение жизненного цикла запросов, так как в ходе их выполнения задействуются асинхронные операции. Почему это плохо? Например, часто разработчики стремятся включать в записи журналов уникальные идентификаторы запросов, что, при анализе таких записей, позволяет выделить те из них, которые относятся к одному и тому же запросу. Сегодня, в 2018 году, сделать это не так уж и легко. В будущем же году нас ждёт кое-что новое, а именно, речь идёт об асинхронных хуках, API async_hooks. Нельзя сказать, что это совершенно новая возможность, речь идёт о том, что она скоро должна выйти из экспериментального режима. Проще говоря, асинхронные хуки позволяют разработчику выполнять собственный код в определённые моменты жизненного цикла асинхронной операции. Учитывая это, можно согласовывать действия, выполняемые асинхронным кодом и сохранять контекст. Эта возможность закладывает основу для разработки пакетов, которые выведут на новый уровень возможности Node.js по отслеживанию выполнения асинхронных операций и по работе с контекстом.
Например, пакет cls-hooked позволяет организовать использование переменных и контекста в течение всего жизненного цикла асинхронной операции. Пакет jaeger-client позволяет визуализировать процесс прохождение запроса по системам, даже по микросервисам и серверам (тут реализован стандарт Javascript OpenTracing API 1.0).
Вот материал, в котором можно найти подробности об использовании API async_hooks.
5. Разберитесь со свежими «бессерверными» технологиями, которые уже вполне готовы для серьёзных проектов и способны убить Kubernetes
Здесь мы используем понятия FaaS (Function as a Service, функция как услуга) и «бессерверные технологии» как синонимы, хотя они означают не одно и то же. В частности, ниже речь пойдёт об облачных FaaS-услугах.
Изначально технология FaaS предназначалась для разработки микрозадач, а не для создания полноценных «микросервисных» приложений. Рост популярности FaaS-платформ привёл к росту интереса к ним поставщиков облачных услуг, FaaS-платформы обросли новыми функциями. Как результат, хотя это и неожиданно, возникает такое ощущение, что в 2019 году FaaS-платформы могут стать основой для серьёзных проектов. Могут ли эти платформы конкурировать с Kubernetes и использоваться для хостинга больших приложений? Некоторые видят в бессерверных вычислениях и FaaS технологии, которые представляют собой нечто совершенно новое, но на практике каждому создателю облачного приложения придётся в 2019 году делать выбор между тремя технологиями. Этот выбор, в буквальном смысле, представлен на сайтах поставщиков облачных услуг. А именно, речь идёт о выборе одного из трёх вариантов:
- Обычный облачный сервер (например VDS от RUVDS)
- Kubernetes
- FaaS
В результате, в наше время очень важно уметь сравнивать возможности Kubernetes с FaaS и предвидеть последствия выбора той или иной технологии.
6. Ознакомьтесь с новшествами JavaScript, которые в ближайшее время войдут в стандарт
Не могу назвать себя приверженцем поиска и использования самых свежих возможностей языка, так как иногда их применение ухудшает простоту и понятность кода. Но время от времени появляются по-настоящему ценные возможности JavaScript (наподобие конструкции async/await два года назад), поэтому полезно заглядывать в список предложений TC39 и на ресурс node.green для того, чтобы заранее знать о новых возможностях, которые могут вам подойти. Вот что интересного я там нашёл:
- Поля классов сейчас находятся на 3 (последней) стадии согласования, они могут войти в стандарт в 2019 году.
- Тип данных BigInt также проходит последнюю стадию согласования. Использование чисел этого типа может помочь в деле организации взаимодействия с микросервисами или любыми системами, в ходе которого используются огромные числа.
- Асинхронные итераторы и метод промисов finally() уже приняты. Если вы пока не обратили на них внимание — ознакомьтесь с ними.
7. Хорошо освойте как минимум одну технологию для создания API. Обратите внимание на GraphQL
REST-API — это замечательный инструмент для решения определённого класса задач. А именно, речь идёт об управлении запросами и модификацией записей в базах данных. Ваша система направлена на работу с финансовыми данными? Вероятно, для обеспечения её работы нужно соблюдение строжайших ограничений и использование тщательно проработанной модели данных, не допускающей неоднозначностей. Технология REST вам в этом случае подойдёт, но она не очень хорошо показывает себя в других, весьма распространённых ситуациях, например тогда, когда выполнение одного и того же запроса может привести к получению разных наборов данных. То же самое касается и работы в условиях низкой скорости соединений, когда нужно, чтобы при работе с неким API передавалось бы как можно меньше данных. К таким ситуациям относятся и соединения между компьютерами, где на первый план выходит высокая скорость связи. Стоит ли в подобных случаях переходить на что-то новое? Нет, не стоит. Лучше всего добавить к тому, что уже используется, что-то новое. API — это не архитектура приложения. Это просто точка доступа к приложению, а значит сосуществовать могут API, созданные с использованием разных инструментов. Даже если все они построены поверх единственного веб-фреймворка наподобие Express.
Какую же технологию изучить? Вероятно, в текущих условиях стоит сделать ставку на технологию GraphQL, которая становится всё популярнее и распространённее. Экосистема этой технологии значительно повзрослела, она обслуживает некоторые весьма популярные сценарии работы с данными — такие, как динамический поиск и взаимодействие с иерархическими источниками данных. С другой стороны, технология gRPC всё ещё представляет собой узкоспециализированное решение, которое хорошо подходит для обеспечения коммуникации между серверами в ситуациях, когда в ходе обмена данными желательно передавать как можно меньше служебной информации (например, речь идёт о системах обмена данными, основанных на схеме «издатель-подписчик», или о таких, где используются сообщения и очереди сообщений). Вот несколько полезных публикаций на эту тему:
8. Используете модульные и интеграционные тесты? Взгляните на совершенно новые техники тестирования
Вы уже знакомы с пирамидой тестов, с модульными, интеграционными и сквозными тестами? Если так — замечательно. Всё это лежит в основе успешных стратегий тестирования. Однако тут надо заметить, что за последние 10 лет мир разработки ПО очень серьёзно изменился, а модели тестирования остались прежними, что ставит нас перед вопросами о том, как тестировать микросервисы, насыщенные интернет-приложения, бессерверные системы. Некоторые современные подходы к тестированию дополняют традиционный набор технологий, а некоторые могут даже его заменить, улучшив тем самым стратегию и результаты тестирования. Вот что можно об этом почитать и посмотреть:
- Тестирование систем, построенных по шаблону Consumer-Driven Contracts, позволяет предотвратить отказ серверных API, используемых микросервисами или клиентами.
- Тестирование при помощи снимков может быть использовано не только во фронтенде, но и в серверных проектах.
- Компонентное тестирование представляет собой сбалансированный подход к тестированию микросервисов.
- Вот видео, где идёт речь о современных подходах к тестированию Node.js-проектов.
9. Приведите свою систему мониторинга приложений в соответствие с практическими рекомендациями из сферы SRE/DevOps
В 2019 году даже приложение среднего размера может состоять из десятков компонентов. Для того чтобы обеспечить бесперебойную работу подобной инфраструктуры, за ней нужно внимательно наблюдать. Несмотря на очевидность вышесказанного, большинство разработчиков всё ещё не считают важным изучение и использование тех рекомендаций по мониторингу приложений и созданию системы оповещений о проблемах, которые могут дать им специалисты, отвечающие за надёжность работы веб-проектов. Например, часто разработчики уделяют основное внимание внутренним показателям производительности систем, таким, как частота процессора или объём оперативной памяти, вместо того, чтобы озаботиться метриками, которые напрямую влияют на конечных пользователей. В частности, речь идёт о частоте возникновения ошибок и о задержках. Это называют«мониторингом, основанным на симптомах проблем». Подобные показатели, ориентированные на пользователей, иногда называют «золотыми сигналами», и вы, возможно, внедряя систему мониторинга, решите начать именно с внедрения подобных метрик. Вот материалы по теме:
- 4 «золотых сигнала» мониторинга.
- Глава, посвящённая мониторингу распределённых систем из книги Site Reliability Engineering, подготовленной специалистами Google.
- Пакет request-stats может пригодиться в сборе соответствующих метрик, которые потом можно передать в систему мониторинга.
10. Улучшайте безопасность проектов, глядя на них с точки зрения злоумышленника, а также изучая способы проведения атак и хакерские инструменты
Если вы не можете думать как тот, кто хочет атаковать вашу систему, это значит, что вы не можете думать и так, как думал бы защитник этой системы. В 2019 году вам не следует ни передавать задачи по защите проектов сторонним организациям, ни полагаться лишь на статические анализаторы безопасности. Сегодня существует огромное количество типов атак (последние тренды в этой сфере — атаки на инфраструктуру разработки и на npm). При этом приложения очень и очень быстро меняются — ещё вчера проект признали хорошо защищённым, а уже завтра в него могут добавить несколько новых AWS-сервисов, несколько новых типов баз данных и новую роль IAM. При этом снова анализировать безопасность проекта будут нескоро. В результате оказывается, что разработчики представляют наибольшую угрозу безопасности для собственных проектов. Решением этой проблемы является их обучение. Это означает, что каждому разработчику веб-проектов необходимо довести выполнение правил безопасности чуть ли не до автоматизма, и, что бы он ни делал, всегда о безопасности помнить.
После того, как вы решите двигаться в подобном направлении, окажется, что учёт безопасности при выполнении любых работ не так уж и страшен. Скажем, ознакомившись с распространёнными способами и инструментами для совершения атак, нарисуйте схему архитектуры своего приложения и подумайте о том, как вы атаковали бы его. Со временем, даже не отдавая себе в этом отчёта, вы начнёте учитывать вопросы безопасности, принимая каждое архитектурное решение и вводя в редакторе каждую новую строку кода. Вот некоторые идеи, касающиеся освоения вопросов безопасности:
- Испытайте OWASP ZAP — многофункциональный инструмент для исследования систем и их взлома, который позволяет даже начинающему изучить уровень безопасности приложения.
- Почитайте этот список рекомендаций по безопасности Node.js, в котором вы найдёте более двух десятков идей атак и примеры кода на JavaScript.
- Запланируйте проведение ежемесячной встречи, посвящённой анализу угроз, на которой команда проекта будет изучать его архитектуру и предлагать атаки на него. Если такая идея кажется вам скучной — можете подобные встречи геймифицировать. Скажем, тех, кто найдёт уязвимость, можно как-то награждать. Ещё можно, например, разбить участников подобной встречи на две команды и устроить между ними соревнование по поиску уязвимостей.
11. Разработайте и применяйте стратегию обновления npm-пакетов. 2018 год показал, что поспешность при их обновлении опасна
Обычно команды разработчика придерживаются одной из двух «стратегий» обновления npm-пакетов. Они либо обновляют их как можно быстрее после выхода их новых версий, иногда даже автоматизируя этот процесс, либо вовсе не имеют стратегии обновления пакетов. При таком подходе пакеты обновляются нерегулярно, а, начиная этот процесс, руководствуются чем-то вроде внезапно пришедшей мысли: «А не обновиться ли нам сегодня?». Хотя первый из этих подходов и выглядит лучше второго, он, что неожиданно, оказался в 2018 году сопряжённым с более высоким риском, чем второй. Проблемы, наподобие той, что произошла с пакетом flat-stream, были обнаружены сообществом в пределах нескольких десятков дней, и те, кто, не спешил обновляться, оказались в безопасности.
Подумайте над формализацией стратегии обновления пакетов, от которых зависит ваш проект, предусмотрите использование средств автоматизации этого процесса. Найдите золотую середину между отказом от обновлений и слишком частым обновлением пакетов. Тут вам может помочь программа npq, выполняющая проверку пакетов при установке и дающая рекомендации. Можете взглянуть на коммерческие проекты вроде greenkeeper. Минус подобных решений заключается в том, что они не могут отложить установку до того момента, когда совершенно точно будет известно, что некий пакет является безопасным.
12. Присмотритесь к поэтапному развёртыванию проектов
Возможно, в 2019 году вы сочтёте разумным выполнять развёртывание проектов в продакшне, пользуясь поэтапной схемой, а не путём мгновенной отправки всего, что было до этого в процессе разработки, на боевой сервер. Этот процесс называют «canary deployment», он даёт более высокий уровень защиты проекта, чем одномоментное развёртывание нового кода. В нём обычно выделяют следующие три этапа:
- Развёртывание. Новый код разворачивают в новом, изолированном продакшн-окружении (на новом сервисе Kubernetes, на новом виртуальном сервере). На этом этапе код пока никого не обслуживает, поэтому сбои в нём вреда причинить не могут.
- Тестирование. Теперь несколько специалистов могут поработать с новым кодом в условиях, максимально приближенных к реальным, так как код развёрнут в продакшне.
- Релиз. После того, как тестирование показало работоспособность нового кода, к нему постепенно дают доступ всё большему количеству пользователей, а после того, как окажется, что работает он достаточно надёжно, постепенно выводят из употребления его старую версию.
Тут стоит сделать одно важное замечание, касающееся того, что выполнение полномасштабных canary-развёртываний в 2019 году всё ещё будет очень дорогим удовольствием. Дело в том, что это требует согласования работы инфраструктурных элементов проекта — таких, как маршрутизация и мониторинг. Таким образом, если вы хотите применить подобную методику, стоит начать с простого, выполняемого отчасти вручную, canary-развёртывания. В частности, это заключается в том, что после успешного завершения первых испытаний, с учётом показателей мониторинга, выполняется ручное добавление в систему серверов с новой версией программного обеспечения. Подробности о canary-релизах можно почитать здесь. Если вы хотите автоматизировать процесс выполнения подобных релизов — обратите внимание на платформу Spinnaker.
13. Ознакомьтесь с технологией Kubernetes, которая завоевала мир
Технология Kubernetes (K8S) представляет собой инфраструктуру для компонентов приложения, которая предоставляет им сетевые ресурсы и обеспечивает автоматизацию развёртывания и масштабирования проектов. Она стала стандартом де-факто в сфере хостинга приложений. Её популярность просто невероятна. Технологию Kubernetes поддерживают все поставщики облачных услуг, она обладает отличной системой расширений, 54% корпоративных пользователей уже обладают как минимум одним K8S-кластером. Если вы лишь собираетесь ознакомиться с этой технологией — вотхороший материал начального уровня о ней. Если вы уже сделали первые шаги в сфере K8S — вот список публикаций, с которыми полезно будет ознакомиться:
Учитывайте то, что каждый час, потраченный вами на изучение Kubernetes, окупится сторицей.
14. Изучите блокчейн-технологии, которые таят в себе очень интересные возможности
Блокчейн-технологии — это не только криптовалюты. Эти технологии можно применять в любых распределённых системах, обрабатывающих некие транзакции.
15. Освойте технологии машинного обучения, или, по крайней мере, научитесь в них ориентироваться
Вероятно, машинное обучение — это один из ведущих трендов современности. К несчастью, я не особенно хорошо знаком с этой темой. В будущем году я планирую с ней разобраться. Как минимум, мне хотелось бы научиться грамотно общаться на темы машинного обучения и уметь находить качественные инструменты из этой сферы (например, библиотеки вроде tensorflow.js и brain.js, которые позволяют решать реальные задачи, не требуя мощной инфраструктуры).
16. Читайте код успешных опенсорсных проектов
Опасайтесь сужения кругозора, которое вызывает долгая работа над одним и тем же проектом с использованием одного и того же набора технологий. Работа в таком режиме, кроме прочего, скрывает от вас альтернативные способы решения ваших задач. Стремитесь к регулярному исследованию чужого кода, в частности — успешных опенсорсных проектов.
17. Углубите свои познания в области Linux, в частности — понимание устройства процессов
Понимание устройства Linux-процессов даст вам реальные преимущества, так как процессы лежат в основе множества задач, связанных с разработкой. Среди них — мониторинг, обеспечение бесперебойной работы проектов (например — перезапуск процессов), работа с Docker, правильное завершение работы систем и многое другое. Постарайтесь разобраться в этапах жизненного цикла процессов, в сигналах, в модели разрешений, в типах процессов, в командах, используемых для управления ими. Вот полезный материал, посвящённый основам работы с процессами Linux.
18. Разберитесь с тем, как работают внутренние механизмы Node.js
Мне нравится высказывание Райана Даля (создателя Node.js): «Вы никогда не сможете понять всё. Но вам нужно стремиться к тому, чтобы понять систему». Хорошее понимание принципов работы платформы окажется ценным навыком при решении сложных проблем, возникающих в продакшне, оно пригодится при разработке вспомогательных инфраструктурных компонентов приложений (вроде средств мониторинга производительности цикла событий). Возможно, вы уже знакомы с основными частями Node.js, таким, как движок V8 и библиотека libuv. Я так думаю, что 2019 год — это отличное время для того, чтобы углубить свои познания в сфере Node.js, и понять, например, что именно происходит внутри циклов событий libuv. Или, возможно, разобраться с тем, как Node.js взаимодействует с подсистемой ввода-вывода операционной системы, на которой работает эта платформа.
Вот материал о том, что происходит в цикле событий. Вот статья, посвящённая написанию npm-пакетов на C/C++. Вот большая публикация о внутренних механизмах Node.js. Вот цикл обучающих статей про Node.js в блоге RUVDS.
19. Учитесь новому, используя научные методы
Этот пункт последний в нашем списке, но он не менее важен, чем другие. Дело в том, что то, чему вы учитесь, то, что вы усваиваете, оказывает влияние на ваш профессиональный рост. Но, при этом, у многих разработчиков нет ни стратегии самообучения, ни стремления освоить эффективные способы обучения, используя научный подход. Представьте себе совещание на тему предотвращения ошибок в JavaScript-коде, связанных с типами данных. Руководитель настаивает на том, чтобы команда использовала бы обычный JavaScript, что позволит обойтись без рефакторинга кодовой базы. Речь идёт о том, что, например TypeScript вам не нужен. Внезапно ваш коллега предлагает использовать flow и всем, кто принимает участие в совещании, эта идея нравится. Тут вы вспоминаете, что как-то читали о flow, но информацию эту вы не усвоили, она, что называется, «в одно ухо влетела, а в другое вылетела». Почему это произошло? Вероятно, тут мы имеем дело с феноменом, который называется «иллюзия компетентности». Он объясняет причину, по которой люди что-либо забывают. Например, вы потратили час ценного времени на чтение некоего материала и думаете, что всё поняли и запомнили, но это — самообман. Через пару дней вы ничего из прочитанного уже не вспомните. Исследования показывают, что если вы попытаетесь потом об этом кому-нибудь рассказать или просто пробежитесь по тому же тексту на следующий день, вы сможете значительно увеличить шансы на то, что вы усвоите то, что прочли. Есть и многие другие техники, которые помогут запоминанию и позволят извлекать нужные фрагменты знаний в правильное время. Поэтому я полагаю, что потратить несколько часов 2019 года на то, чтобы научиться учиться — это стоящее вложение времени.
Вот отличный курс об обучении. Вот материал о том, как организовывать информацию для её эффективного усвоения. Если вы читаете о новой технологии — сравните её с тем, с чем вы уже знакомы, поговорите о ней с коллегами, задайте себе вопрос о том, зачем она нужна, нарисуйте её схему, перечитайте выводы материала об этой технологии. Всё это поможет вашему мозгу усвоить то, что вы узнали, связать это с существующими знаниями, а значит, когда вам такая информация понадобится, вы сможете ей воспользоваться.
Итоги
Мы рассмотрели 19 рекомендаций, которые позволят Node.js-разработчикам, нашедшим среди них что-то для себя подходящее, профессионально вырасти в 2019 году. Надеемся, вы встретили здесь что-то такое, что вам пригодится.