🥷 Лайфхаки по работе в терминале
|
Подборка советов от опытного разработчика поможет значительно повысить эффективность работы в командной строке, автоматизировать рутинные задачи и упростить сложные операции. |
Редактирование команд в текстовом редакторе |
Часто при работе в терминале приходится набирать длинные и сложные команды, которые неудобно редактировать даже с помощью горячих клавиш. На помощь придет ваш дефолтный текстовый редактор: |
- Нажмите Ctrl+X, затем Ctrl+E в Bash или Alt+E в Fish. Это откроет ваш стандартный текстовый редактор.
- Отредактируйте команду и сохраните изменения.
- Команда будет выполнена после закрытия редактора.
|
Такие команды удобнее править в редакторе |
Автоматизация с помощью tmux |
tmux – мощный терминальный мультиплексор, который позволяет создавать и управлять несколькими терминальными сессиями одновременно. Как отмечает автор оригинала этой подборки, tmux может автоматизировать все действия, которые не поддаются автоматизации с помощью обычных скриптов. С помощью скриптов для tmux можно не только автоматизировать повторяющиеся действия (например, создание одинаковых сессий на разных серверах), но и: |
- Программно читать вывод терминала и реагировать на события.
- Передавать данные между панелями.
- Управлять поведением физического устройства – останавливать и перезагружать в нужные моменты, менять конфигурацию и т. п.
- Автоматически выполнять команды в нескольких панелях одновременно.
|
tmux позволяет передавать данные из одной панели в другую |
Поиск и выбор с помощью fzf |
fzf – продвинутый инструмент для нечеткого поиска. Работает с любыми текстовыми данными – списками, файлами, процессами, названиями хостов, закладками, коммитами Git и т. п. Отлично справляется с интерактивным выбором опций в пользовательских скриптах – можно, например, создать скрипт для выбора веток Git или для запуска нужных облачных сервисов, которые предусматривают выбор определенных параметров. |
Использование /dev/stdin вместо heredoc |
Heredoc предоставляет возможность вставки многострочного текста в командную строку. Однако у heredoc довольно сложный синтаксис, к тому же не все оболочки поддерживают этот способ ввода. Альтернатива – /dev/stdin – делает почти все то же самое, но проще. Недостатки – в отличие от heredoc, не работает в скриптах и не сохраняет команды в истории оболочки. |
Многострочный ввод с помощью /dev/stdin |
Эта функция позволяет использовать одно SSH-соединение для нескольких сессий. Включается очень просто – достаточно добавить эти строки в ~/.ssh/config: |
Host * ControlPath /tmp/ssh-%r@%h:%p
ControlMaster auto
ControlPersist 10m
|
- git checkout - – быстрое переключение на предыдущую активную ветку Git. Аналогично команде cd - для перехода в предыдущий каталог.
- $_ или !$ в Bash позволяет использовать последний аргумент предыдущей команды.
- Alt+. в Bash и Fish – быстрый способ вставить последний аргумент предыдущей команды.
- Пробел перед командой исключает эту команду из истории.
- pushd и popd сохраняют состояние перехода между директориями. Более простой способ управления директориями используется в оболочке Fish – nextd и prevd.
- locate обеспечивает индексацию и мгновенный поиск файлов.
- command | sudo tee file вместо sudo command > file позволяет запускать команду с правами администратора и перенаправлять ее вывод в файл с правами доступа.
- <<< (herestring) – позволяет передать строку в качестве входных данных для команды. Например, cat - <<< "Hello, world!" выведет "Hello, world!".
- vim scp://<user>@<host>/<absolute-path> позволяет редактировать удаленный файл напрямую через SSH.
- vim - передает вывод команды в Vim, который гораздо удобнее less.
|
🪶 Как разработать клон SQLite с нуля
|
Чтобы помочь разработчикам лучше понять, что происходит под капотом базы данных, Джеффри Копин решил шаг за шагом показать, как сделать собственную версию СУБД SQLite. Автор использует Rust, но объяснения всех этапов работы настолько детальны и понятны, что реализация этого проекта на любом другом языке не составит особого труда. В первой части туториала показано создание базовой структуры для чтения файла базы данных SQLite и разработка функциональности для извлечения из него информации о таблицах. |
Чтение и разбор заголовка базы данных: |
- Открытие файла базы данных.
- Чтение первых 100 байт для получения заголовка.
- Извлечение информации о размере страницы.
|
Реализация Pager (системы управления страницами): |
- Создание структуры для чтения и кэширования страниц из файла.
- Реализация функций для загрузки конкретных страниц по номеру.
|
Декодирование страниц типа table btree leaf: |
- Разбор заголовка страницы.
- Извлечение указателей на ячейки.
- Декодирование отдельных ячеек, содержащих данные строк.
|
Реализация формата записи SQLite: |
- Создание структур для представления типов полей и заголовков записей.
- Разработка функций для разбора заголовков записей и извлечения значений полей.
|
Создание Cursor и Scanner: |
- Реализация Cursor для удобной работы с отдельными записями.
- Создание Scanner для итерации по записям на странице.
|
Работа с таблицей sqlite_master: |
- Реализация функции для чтения схемы базы данных из специальной таблицы sqlite_master.
- Извлечение информации о таблицах из этой системной таблицы.
|
Реализация команды .tables: |
- Создание функции для перебора записей в sqlite_master.
- Фильтрация записей типа "table".
- Вывод имен таблиц.
|
Создание простого REPL-интерфейса: |
Код готового проекта можно посмотреть в репозитории rqlite. |
🐘 Иллюзия согласованности в конечном счете в PostgreSQL и что с ней делать
|
В PostgreSQL и многих других СУБД для обеспечения согласованности данных при одновременной работе нескольких пользователей используется метод многоверсионного параллельного контроля (MVCC). MVCC создает снимок базы для каждой транзакции, позволяя параллельным операциям видеть согласованное состояние данных. Хотя PostgreSQL обеспечивает строгую согласованность (все транзакции видят последовательное и правильное состояние данных), клиенты могут воспринимать базу как согласованную в конечном счете. Это приводит к недоразумениям при выводе данных на фронтенде – порядок записей может меняться при последующих запросах. Это происходит из-за того, как MVCC обрабатывает параллельные транзакции и как клиент видит результаты этих транзакций:
|
- Когда несколько транзакций выполняются одновременно, они могут завершаться в непредсказуемом порядке.
- Клиент, делающий последовательные запросы, может видеть результаты этих транзакций в порядке их завершения, а не в порядке их начала.
|
- Представьте, что два процесса (A и B) одновременно вставляют данные в таблицу.
- Процесс A начинается первым, но завершается позже процесса B.
- Клиент, делающий запрос сразу после завершения B, но до завершения A, увидит данные от B, но не от A.
- При повторном запросе после завершения обоих процессов клиент увидит данные и от A, и от B.
|
В результате клиент может пропустить некоторые записи или увидеть их в неожиданном порядке при попытке последовательно обработать все данные, например, при использовании курсорной пагинации. Но сама база данных при этом всегда находится в согласованном состоянии! Чаще всего для решения этой проблемы используются два способа:
| - Можно заставить процессы ждать своей очереди при добавлении данных – с помощью дополнительной таблицы для хранения последовательности и использования триггеров для установки значения последовательности при вставке записей. Этот метод гарантирует, что данные будут добавляться в определенном порядке, но может замедлить работу.
- Вместо изменения способа добавления данных можно изменить способ их чтения – то есть читать только те записи, которые точно завершили процесс добавления. Этот подход позволяет сохранить высокую производительность записи, но требует более сложной логики на стороне клиента для обработки потенциальных изменений порядка записей.
|
Автор этой публикации предлагает более оптимальное решение – с использованием рекомендательных блокировок. Этот метод позволяет приложению определять собственные семантики блокировок, которые система не соблюдает по умолчанию. Приложение должно самостоятельно управлять этими блокировками, учитывая их назначение и контекст использования. Решение работает так: |
- Получение блокировки на уровне транзакции. Для каждой операции вставки в таблицу access_logs используется две рекомендательные блокировки. Первая блокировка (pg_try_advisory_xact_lock_shared(1, 0)) указывает, что текущая сессия занимается операцией вставки в access_logs. Вторая блокировка (pg_try_advisory_xact_lock((select last_value + 1 from access_logs_seq))) устанавливает минимальное значение seq, которое будет использоваться в текущей транзакции.
- Определение безопасного «потолка» для чтения. Для определения минимального значения seq среди всех активных транзакций используется запрос к таблице pg_locks. Этот запрос позволяет найти минимальное значение objid для блокировок с classid=0, что соответствует второй блокировке, установленной при вставке.
- Чтение данных с учетом предела. При чтении данных из таблицы access_logs используется полученное минимальное значение seq в качестве верхнего предела для фильтрации записей.
|
Этот подход сохраняет высокую скорость записи и гарантирует, что читаемые данные будут согласованы и не будут включать записи, которые еще могут быть изменены другими транзакциями. |
🧩 9 основных паттернов для проектирования распределенных систем
|
Распределенные системы – это комплекс взаимосвязанных компьютеров или программных компонентов, которые взаимодействуют друг с другом для достижения общей цели. Особенности: |
- Компоненты системы распределены по сети и координируют свои действия путем обмена сообщениями.
- Компоненты разнородны и автономны.
- Набор компонентов воспринимается пользователями как единая связанная система.
|
- Повышенная надежность и отказоустойчивость.
- Масштабируемость.
- Возможность распределения ресурсов.
- Повышенная производительность за счет параллельной обработки.
|
Понимание принципов работы распределенных систем исключительно важно для разработки современных приложений и сервисов. Разобраться в этих принципах помогут основные паттерны проектирования. |
Peer-to-Peer (P2P, одноранговая/пиринговая сеть) |
Этот паттерн позволяет компонентам системы напрямую общаться друг с другом без центрального координатора. Каждый узел в сети может быть как клиентом, так и сервером. Нужен для: |
- Создания децентрализованных систем, где нет единой точки отказа.
- Эффективного обмена ресурсами между узлами.
- Повышения масштабируемости и отказоустойчивости системы.
|
Примеры использования: файлообменные сети, блокчейн-приложения, распределенные вычисления. |
Представляет собой единую точку входа для клиентских запросов к различным внутренним сервисам приложения. Нужен для: |
- Упрощения взаимодействия клиентов с сервисами.
- Централизованного управления безопасностью, аутентификацией и ограничением запросов.
- Абстрагирования клиентов от сложности внутренней архитектуры.
|
Широко используется в микросервисной архитектуре для управления доступом к различным сервисам. |
Pub-Sub (Publish-Subscribe, Издатель-подписчик) |
В этом паттерне издатели отправляют сообщения в определенные темы, а подписчики получают сообщения из интересующих их тем. Нужен для: |
- Обеспечения слабой связанности между компонентами системы.
- Асинхронной коммуникации между частями системы.
- Масштабируемости и отказоустойчивости в распределенных системах.
|
Применяется в брокерах сообщений, IoT-платформах, event-driven (событийно-ориентированных) архитектурах. |
Request-Response (Запрос-ответ) |
Базовая модель взаимодействия, где клиент отправляет запрос серверу и ждет ответа. Нужен для: |
- Обеспечения предсказуемого поведения в распределенных системах.
- Поддержки обработки ошибок и транзакционности.
- Простых в реализации и использовании систем.
|
Широко используется в веб-приложениях, REST API, RPC-системах. | Event Sourcing (Источник событий) |
Этот паттерн предполагает хранение состояния приложения как последовательности неизменяемых событий. Нужен для: |
- Сохранения полной истории изменений состояния системы.
- Возможности отката состояния системы на любой момент в прошлом.
- Улучшения аудита и отладки.
|
Применяется в финансовых системах, инструментах для совместного редактирования, системах с высокими требованиями к аудиту. |
ETL (Extract, Transform, Load – Извлечение, преобразование, загрузка) |
Паттерн для извлечения данных из разных источников, их преобразования и загрузки в целевое хранилище. Нужен для: |
- Интеграции данных из разнородных источников.
- Стандартизации и очистки данных.
- Подготовки данных для анализа и отчетности.
|
Широко используется в бизнес-аналитике, хранилищах данных, системах обработки больших данных. | Batch Processing (Сбор и пакетная обработка данных) |
Этот паттерн предполагает накопление данных или операций перед их обработкой единым пакетом. Нужен для: |
- Оптимизации использования ресурсов системы.
- Уменьшения накладных расходов на обработку отдельных элементов.
- Повышения эффективности при работе с большими объемами данных.
|
Применяется в системах обработки данных, ETL-процессах, распределенных вычислениях. |
Stream Processing (Потоковая обработка) |
Этот паттерн обеспечивает непрерывную обработку потоков данных в реальном времени. Нужен для: |
- Обработки данных с минимальной задержкой.
- Анализа и реагирования на события в режиме реального времени.
- Работы с непрерывными потоками данных.
|
Используется в финансовых системах, IoT-приложениях, системах мониторинга и безопасности. |
Orchestration (Оркестрация) |
Паттерн предполагает использование центрального координатора (оркестратора) для управления взаимодействием между распределенными компонентами или сервисами. Нужен для: |
- Координации сложных бизнес-процессов.
- Управления зависимостями между задачами.
- Централизованной обработки ошибок и исключений.
|
Применяется в системах автоматизации рабочих процессов, управлении бизнес-процессами, оркестрации микросервисов. Как видно, каждый из этих паттернов решает определенные проблемы, помогая создавать более эффективные, масштабируемые и надежные распределенные системы.
|
|
|
Понравилась ли вам эта рассылка? |
|
|
Вы получили это письмо, потому что подписались на нашу рассылку. Если вы больше не хотите получать наши письма, нажмите здесь.
|
|
|
|