Русский
Русский
English
Статистика
Реклама

Utils

Тотальный JavaScript изучаем JS с акцентом на практической составляющей

22.02.2021 16:14:10 | Автор: admin


Доброго времени суток, друзья!

Когда речь заходит об изучении JavaScript, будь то первое знакомство с языком или углубление имеющихся знаний, найти в интернетах теоретические материалы не составляет особого труда. Мой топ-5:


Однако, когда дело касается практических аспектов JavaScript, информацию приходится собирать буквально по крупицам. Собственно, этим я и занимался на протяжении последних 4-5 месяцев.

Предлагаю вашему вниманию Тотальный JavaScript.

Вот что вы найдете в этом репозитории:

  • Огромное количество сниппетов (утилит, вспомогательных функций), разделенных по типам данных не могу назвать точного количества (порядка 4000 строк кода без комментариев и пробелов). Следует отметить, что не все функции являются настоящими сниппетами с точки зрения возможности их использования (как есть) в реальных приложениях, некоторые всего лишь эксперименты, демонстирующие те или иные (безграничные?) возможности языка. Коллекция все время пополняется
  • 230 практических вопросов приводится пример кода, необходимо выполнить его в уме и решить, что будет выведено в консоль. Конечно, на практике мы редко занимается чем-то подобным, ведь гораздо легче и, главное, быстрее законсолить кусок подозрительного кода. Однако, на мой взгляд, умение решать подобные задачи как нельзя лучше демонстрирует понимание основных принципов и характерных особенностей работы JavaScript. В качестве недостатка этого раздела отмечу почти полное отсутствие вопросов по классам и this. Постараюсь в ближайшем будущем его устранить
  • 68 задач разного уровня сложности подборка задач из учебника Ильи Кантора (большинство), немного адаптированных под нужды реальных приложений. Структура раздела, в основном, следует структуре учебника с небольшими лирическими отступлениями
  • Паттерны проектирования подробное описание и примеры всех паттернов, которые называет Банда Четырех в своей книге Паттерны объектно-ориентированного программирования, на JavaScript (также в разделе имеются примеры на TypeScript смотрите исходный код). При подготовке данного раздела многое позаимствовано у Refactoring Guru, за что ему (или им) огромное спасибо
  • Что за черт, JavaScript? список тонких моментов работы JavaScript. Этот раздел не слишком актуален, учитывая возможности современного JS, однако интересен тем, что позволяет узнать, каким был язык раньше, до того, как завоевал мир веб-разработки. Де факто, он остается прежним, но следование простым правилам (например, использование const или let вместо var или "===" вместо "==") позволяет решить большую часть проблем, с которыми сталкивались разработчики в прошлом

Уверен, что каждый найдет для себя что-нибудь интересное.

Также в репозитории имеется ссылка на приложение с вопросами (список и интерективная викторина) и задачами. Оно вполне работоспособное (и даже прогрессивное), но, признаюсь, нуждается в существенной переработке. Займусь этим, когда появится свободное время.

Как всегда, буду рад любой форме обратной связи. При обнаружении опечаток, ошибок, неточностей и, особенно, неработающего кода (код протестирован, но никто не застрахован от ошибок) не стесняйтесь писать в личку и делать пуллы.

Благодарю за внимание. Всех, кому дым отечества и сладок, и приятен, с наступающим праздником.
Подробнее..

Перевод Лучшие практики bash-скриптов краткое руководство по надежным и производительным скриптам bash

17.08.2020 18:04:48 | Автор: admin

Shell wallpaper by manapi

Отладка сценариев bash это как поиск иголки в стоге сена, тем более, когда новые дополнения появляются в существующей кодовой базе без своевременного рассмотрения вопросов структуры, логирования и надежности. В таких ситуациях можно оказаться как из-за собственных ошибок, так и при управлении сложными нагромождениями скриптов.

Команда Mail.ru Cloud Solutions перевела статью с рекомендациям, благодаря которым вы сможете лучше писать, отлаживать и поддерживать свои сценарии. Хотите верьте, хотите нет, но ничто не может сравниться с удовлетворением от написания чистого, готового к использованию bash-кода, который работает каждый раз.

В статье автор делится тем, что узнал за последние несколько лет, а также некоторыми распространенными ошибками, которые заставали его врасплох. Это важно, потому что каждый разработчик программного обеспечения в определенный момент своей карьеры работает со сценариями для автоматизации рутинных рабочих задач.

Обработчики ловушек


Большинство скриптов bash, с которыми я сталкивался, никогда не использовали эффективный механизм очистки, когда во время выполнения скрипта происходит что-то неожиданное.

Неожиданности могут возникнуть извне, например получение сигнала от ядра. Обработка таких случаев чрезвычайно важна для того, чтобы сценарии были достаточно надежными для запуска в продакшен-системах. Я часто использую обработчики выхода, чтобы реагировать на такие сценарии:

function handle_exit() {  // Add cleanup code here  // for eg. rm -f "/tmp/${lock_file}.lock"  // exit with an appropriate status code}  // trap <HANDLER_FXN> <LIST OF SIGNALS TO TRAP>trap handle_exit 0 SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM

trap это встроенная команда оболочки, помогающая вам зарегистрировать функцию очистки, которая вызывается в случае каких-либо сигналов. Однако следует соблюдать особую осторожность с такими обработчиками, как SIGINT, который вызывает прерывание сценария.

Кроме того, в большинстве случаев следует ловить только EXIT, но идея в том, что вы действительно можете настроить поведение скрипта для каждого отдельного сигнала.

Встроенные функции set быстрое завершение при ошибке


Очень важно реагировать на ошибки, как только они возникают, и быстро прекращать выполнение. Ничего не может быть хуже, чем продолжать выполнение команды вроде такой:

rm -rf ${directory_name}/*

Обратите внимание, что переменная directory_name не определена.

Для обработки таких сценариев важно использовать встроенные функции set, такие как set -o errexit, set -o pipefail или set -o nounset в начале скрипта. Эти функции гарантируют, что ваш скрипт завершит работу, как только он встретит любой ненулевой код завершения, использование неопределенных переменных, неправильные команды, переданные по каналу и так далее:

#!/usr/bin/env bashset -o errexitset -o nounsetset -o pipefailfunction print_var() {  echo "${var_value}"}print_var$ ./sample.sh./sample.sh: line 8: var_value: unbound variable

Примечание: встроенные функции, такие как set -o errexit, выйдут из скрипта, как только появится необработанный код возврата (кроме нуля). Поэтому лучше ввести пользовательскую обработку ошибок, например:

#!/bin/basherror_exit() {  line=$1  shift 1  echo "ERROR: non zero return code from line: $line -- $@"  exit 1}a=0let a++ || error_exit "$LINENO" "let operation returned non 0 code"echo "you will never see me"# run it, now we have useful debugging output$ bash foo.shERROR: non zero return code from line: 9 -- let operation returned non 0 code

Подобное написание скриптов заставляет вас внимательнее относиться к поведению всех команд в скрипте и предусматривать возможность возникновения ошибки прежде, чем она застанет врасплох.

ShellCheck для выявления ошибок во время разработки


Стоит интегрировать что-то вроде ShellCheck в ваши конвейеры разработки и тестирования, чтобы проверять ваш код bash на применение лучших практик.

Я использую его в своих локальных средах разработки, чтобы получать отчеты о синтаксисе, семантике и некоторых ошибках в коде, которые я мог пропустить при разработке. Это инструмент статического анализа для ваших скриптов bash, и я настоятельно рекомендую его применять.

Использование своих exit-кодов


Коды возврата в POSIX это не просто ноль или единица, а ноль или ненулевое значение. Используйте эти возможности для возврата пользовательских кодов ошибок (между 201-254) для различных случаев ошибок.

Эта информация может затем использоваться другими сценариями, которые обертывают ваш, чтобы точно понять, какой тип ошибки произошел, и реагировать соответствующим образом:

#!/usr/bin/env bashSUCCESS=0FILE_NOT_FOUND=240DOWNLOAD_FAILED=241function read_file() {  if ${file_not_found}; then    return ${FILE_NOT_FOUND}  fi}

Примечание: пожалуйста, будьте особенно осторожны с именами переменных, которые вы определяете, чтобы не допустить случайного переопределения переменных среды.

Функции-логгеры


Красивое и структурированное ведение логов важно, чтобы легко понять результаты выполнения вашего скрипта. Как и в других языках программирования высокого уровня, я всегда использую в моих скриптах bash собственные функции логирования, такие как __msg_info, __msg_error и так далее.

Это помогает обеспечить стандартизированную структуру ведения логов, внося изменения только в одном месте:

#!/usr/bin/env bashfunction __msg_error() {    [[ "${ERROR}" == "1" ]] && echo -e "[ERROR]: $*"}function __msg_debug() {    [[ "${DEBUG}" == "1" ]] && echo -e "[DEBUG]: $*"}function __msg_info() {    [[ "${INFO}" == "1" ]] && echo -e "[INFO]: $*"}__msg_error "File could not be found. Cannot proceed"__msg_debug "Starting script execution with 276MB of available RAM"

Я обычно стараюсь иметь в своих скриптах какой-то механизм __init, где такие переменные логгера и другие системные переменные инициализируются или устанавливаются в значения по умолчанию. Эти переменные также могут устанавливаться из параметров командной строки во время вызова скрипта.

Например, что-то вроде:

$ ./run-script.sh --debug

Когда такой скрипт выполняется, в нем гарантировано, что общесистемные настройки установлены в значениях по умолчанию, если они обязательны, или, по крайней мере, инициализированы чем-то соответствующим, если это необходимо.

Я обычно основываю выбор, что инициализировать, а что нет, на компромиссе между пользовательским интерфейсом и деталями конфигураций, в которые пользователь может/должен вникнуть.

Архитектура для повторного использования и чистого состояния системы


Модульный / многоразовый код


 framework    common       loggers.sh       mail_reports.sh       slack_reports.sh    daily_database_operation.sh

Я держу отдельный репозиторий, который можно использовать для инициализации нового проекта/скрипта bash, который хочу разработать. Всё, что можно использовать повторно, может быть сохранено в репозитории и получено в других проектах, которые хотят использовать такие функциональные возможности. Такая организация проектов значительно уменьшает размер других скриптов, а также гарантирует, что кодовая база мала и легко тестируема.

Как и в приведенном выше примере, все функции ведения логов, такие как __msg_info, __msg_error и другие, например отчеты по Slack, содержатся отдельно в common/* и динамически подключаются в других сценариях, вроде daily_database_operation.sh.

Оставьте после себя чистую систему


Если вы загружаете какие-то ресурсы во время выполнения сценария, рекомендуется хранить все такие данные в общем каталоге со случайным именем, например /tmp/AlRhYbD97/*. Вы можете использовать генераторы случайного текста для выбора имени директории:

rand_dir_name="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)"

После завершения работы очистка таких каталогов может быть обеспечена в обработчиках ловушек, обсуждаемых выше. Если об удалении временных директорий не позаботиться, они накапливаются, и на каком-то этапе вызывают неожиданные проблемы на хосте, например заполненный диск.

Использование lock-файлов


Часто нужно обеспечить выполнение только одного экземпляра сценария на хосте в любой момент времени. Это можно сделать с помощью lock-файлов.

Я обычно создаю lock-файлы в /tmp/project_name/*.lock и проверяю их наличие в начале скрипта. Это помогает корректно завершить работу скрипта и избежать неожиданных изменений состояния системы другим сценарием, работающим параллельно. Lock-файлы не нужны, если вам необходимо, чтобы один и тот же скрипт выполнялся параллельно на данном хосте.

Измерить и улучшить


Нам часто приходится работать со сценариями, которые выполняются в течение длительного периода времени, например ежедневными операциями с базами данных. Такие операции обычно включают в себя последовательность шагов: загрузка данных, проверка на наличие аномалий, импорт данных, отправка отчетов о состоянии и так далее.

В таких случаях я всегда стараюсь разбивать сценарий на отдельные маленькие скрипты и сообщать об их состоянии и времени выполнения с помощью:

time source "${filepath}" "${args}">> "${LOG_DIR}/RUN_LOG" 2>&1

Позже я могу посмотреть время выполнения с помощью:

tac "${LOG_DIR}/RUN_LOG.txt" | grep -m1 "real"

Это помогает мне определить проблемные/медленные области в скриптах, которые нуждаются в оптимизации.

Удачи!

Что еще почитать:

  1. Go и кеши GPU.
  2. Пример event-driven приложения на основе вебхуков в объектном S3-хранилище Mail.ru Cloud Solutions.
  3. Наш телеграм-канал о цифровой трансформации.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru