Шаблоны (паттерны) решения задач по Структурами данных и алгоритмам (Data Structures and Algorithms / DSA)
(продолжение в следующем посте)
(продолжение в следующем посте)
❤3👍3🤝3
Шаблоны (паттерны) решения задач по Структурами данных и алгоритмам (Data Structures and Algorithms / DSA)
(продолжение предыдущего поста)
1. Array / String Inputs (Массивы / строки):
1. Отсортирован ли массив?
→ Использовать бинарный поиск, два указателя или префиксные суммы.
2. Задачи оптимизации (максимум/минимум/подмассив)?
→ Подумать о скользящем окне, динамическом программировании или жадных алгоритмах.
3. Поиск дубликатов, подсчёта или частот?
→ Использовать HashMap, HashSet или массив для подсчёта.
4. Нужны подстроки или подмассивы фиксированного размера?
→ Применить скользящее окно с двумя указателями.
5. Часто встречающиеся минимум/максимум в окне?
→ Использовать монотонную очередь, deque или кучу.
6. Генерация подмножеств, перестановок, комбинаций?
→ Использовать обратный ход (backtracking).
7. Сопоставление или разбор символов?
→ Использовать стек, особенно для сбалансированных скобок, инфиксной/постфиксной записи.
2. Graph Inputs (Графы):
1. Кратчайший путь в невзвешенном графе?
→ Использовать поиск в ширину (BFS).
2. Кратчайший путь в взвешенном графе?
→ Использовать алгоритм Дейкстры, Беллмана-Форда или A*.
3. Связные компоненты / обнаружение циклов?
→ Использовать DFS или Union-Find (DSU).
4. Топологическая сортировка?
→ Использовать алгоритм Кана или DFS с набором посещённых вершин.
5. Оптимизация, например, MST (минимальное остовное дерево)?
→ Использовать алгоритмы Крускала или Прима.
3. Linked List Inputs (Связанные списки):
1. Обнаружение циклов?
→ Использовать «медленный и быстрый указатели» (алгоритм Флойда).
2. Перевороты или частичные изменения?
→ Использовать жонглирование указателями: prev, curr, next.
3. Пересечение или средний узел?
→ Использовать два указателя.
4. Tree Inputs (Часто бинарные деревья):
1. Обходы?
→ Использовать inorder, preorder, postorder или обход по уровням (BFS).
2. Проверка сбалансированности или расчёт диаметра?
→ Использовать postorder + расчёт высоты.
3. Наименьший общий предок?
→ Использовать рекурсивный DFS или карту родителей + набор предков.
5. Dynamic Programming Use-Cases (Случаи применения динамического программирования):
1. Оптимальный выбор / перекрывающиеся подзадачи?
→ Использовать ДП с мемоизацией (сверху вниз) или табуляцией (снизу вверх).
2. Задачи типа «подмножество» или "knapsack"?
→ Использовать 1D/2D массивы ДП.
3. Сопоставление строк или редактирование?
→ Использовать матрицу ДП (например, расстояние редактирования, LCS).
(продолжение предыдущего поста)
1. Array / String Inputs (Массивы / строки):
1. Отсортирован ли массив?
→ Использовать бинарный поиск, два указателя или префиксные суммы.
2. Задачи оптимизации (максимум/минимум/подмассив)?
→ Подумать о скользящем окне, динамическом программировании или жадных алгоритмах.
3. Поиск дубликатов, подсчёта или частот?
→ Использовать HashMap, HashSet или массив для подсчёта.
4. Нужны подстроки или подмассивы фиксированного размера?
→ Применить скользящее окно с двумя указателями.
5. Часто встречающиеся минимум/максимум в окне?
→ Использовать монотонную очередь, deque или кучу.
6. Генерация подмножеств, перестановок, комбинаций?
→ Использовать обратный ход (backtracking).
7. Сопоставление или разбор символов?
→ Использовать стек, особенно для сбалансированных скобок, инфиксной/постфиксной записи.
2. Graph Inputs (Графы):
1. Кратчайший путь в невзвешенном графе?
→ Использовать поиск в ширину (BFS).
2. Кратчайший путь в взвешенном графе?
→ Использовать алгоритм Дейкстры, Беллмана-Форда или A*.
3. Связные компоненты / обнаружение циклов?
→ Использовать DFS или Union-Find (DSU).
4. Топологическая сортировка?
→ Использовать алгоритм Кана или DFS с набором посещённых вершин.
5. Оптимизация, например, MST (минимальное остовное дерево)?
→ Использовать алгоритмы Крускала или Прима.
3. Linked List Inputs (Связанные списки):
1. Обнаружение циклов?
→ Использовать «медленный и быстрый указатели» (алгоритм Флойда).
2. Перевороты или частичные изменения?
→ Использовать жонглирование указателями: prev, curr, next.
3. Пересечение или средний узел?
→ Использовать два указателя.
4. Tree Inputs (Часто бинарные деревья):
1. Обходы?
→ Использовать inorder, preorder, postorder или обход по уровням (BFS).
2. Проверка сбалансированности или расчёт диаметра?
→ Использовать postorder + расчёт высоты.
3. Наименьший общий предок?
→ Использовать рекурсивный DFS или карту родителей + набор предков.
5. Dynamic Programming Use-Cases (Случаи применения динамического программирования):
1. Оптимальный выбор / перекрывающиеся подзадачи?
→ Использовать ДП с мемоизацией (сверху вниз) или табуляцией (снизу вверх).
2. Задачи типа «подмножество» или "knapsack"?
→ Использовать 1D/2D массивы ДП.
3. Сопоставление строк или редактирование?
→ Использовать матрицу ДП (например, расстояние редактирования, LCS).
👍7❤4✍3
Вышла новая версия языка Ruby - Ruby 4.0.0
Ruby 4.0.0 включает ряд значительных нововведений и улучшений, направленных на повышение производительности, безопасности и удобства работы с языком. Некоторые из ключевых изменений:
1. ZJIT — новый JIT-компилятор. ZJIT (Just-In-Time компилятор) дополняет существующий YJIT. В отличие от YJIT, который использует подход ленивого создания версий базовых блоков, ZJIT основан на более традиционной методологии компиляции на уровне методов, а не локальных участков байткода. Для работы с ZJIT требуется Rust версии 1.85.0 или новее. Чтобы активировать ZJIT, можно использовать флаг
2. Ruby::Box — экспериментальная функция изолированных пространств имён. Позволяет создавать отдельные «боксы», в которых код выполняется с собственными глобальными переменными, константами и определениями классов. Это полезно, например, для одновременной загрузки разных версий одной библиотеки. Чтобы активировать Ruby::Box, нужно установить переменную окружения
3. Переработанный API Ractor. Для коммуникации между Ractors теперь используется
4. Логические операторы в начале новой строки. В Ruby 4.0 теперь разрешено размещать логические операторы (
5. `instance_variables_to_inspect`. Новая функция позволяет контролировать, какие переменные экземпляра отображаются в выводе метода
6. `Set` стал базовым классом. Ранее
7. Новые методы в `Math`. Добавлены методы
8. Другие изменения:
-
-
-
-
- RJIT удалён, остались только YJIT и ZJIT.
- Юникод обновлён до версии 17.0.
- В Windows прекращена поддержка версий MSVC старше 14.0 (
В целом, Ruby 4.0 закладывает основу для будущих улучшений, экспериментальных функций и развития параллельного программирования. При этом в большинстве случаев обновление должно пройти гладко, так как нет крупных ломающих изменений.
https://www.ruby-lang.org/en/news/2025/12/25/ruby-4-0-0-released/
Ruby 4.0.0 включает ряд значительных нововведений и улучшений, направленных на повышение производительности, безопасности и удобства работы с языком. Некоторые из ключевых изменений:
1. ZJIT — новый JIT-компилятор. ZJIT (Just-In-Time компилятор) дополняет существующий YJIT. В отличие от YJIT, который использует подход ленивого создания версий базовых блоков, ZJIT основан на более традиционной методологии компиляции на уровне методов, а не локальных участков байткода. Для работы с ZJIT требуется Rust версии 1.85.0 или новее. Чтобы активировать ZJIT, можно использовать флаг
--zjit: ruby --zjit my_noscript.rb. Хотя ZJIT быстрее интерпретируемого кода, для продакшена по-прежнему рекомендуется использовать YJIT. 2. Ruby::Box — экспериментальная функция изолированных пространств имён. Позволяет создавать отдельные «боксы», в которых код выполняется с собственными глобальными переменными, константами и определениями классов. Это полезно, например, для одновременной загрузки разных версий одной библиотеки. Чтобы активировать Ruby::Box, нужно установить переменную окружения
RUBY_BOX=1. 3. Переработанный API Ractor. Для коммуникации между Ractors теперь используется
Ractor::Port. Удалённы старые методы Ractor.yield и Ractor#take. Проделана большая работа по повышению стабильности, производительности и удобства использования Ractor. Эти улучшения приближают реализацию Ractor к выходу из экспериментального статуса. Добавлены методы Ractor#join и Ractor#value, аналогичные тем, что есть у Thread. 4. Логические операторы в начале новой строки. В Ruby 4.0 теперь разрешено размещать логические операторы (
&&, ||, and, or) в начале новой строки. Это улучшает читаемость сложных условных выражений и соответствует распространённым предпочтениям форматирования. 5. `instance_variables_to_inspect`. Новая функция позволяет контролировать, какие переменные экземпляра отображаются в выводе метода
inspect при отладке. Это помогает сделать вывод более лаконичным и сфокусированным на важном состоянии объекта. 6. `Set` стал базовым классом. Ранее
Set был классом из стандартной библиотеки, теперь он включён в ядро языка, и его не нужно подключать с помощью require 'set'. 7. Новые методы в `Math`. Добавлены методы
Math.log1p и Math.expm1 для более точных вычислений с малыми числами. Math.log1p(x) вычисляет log(1 + x), а Math.expm1(x)` — `exp(x) - 1. Эти методы полезны в научных расчётах и финансовых вычислениях. 8. Другие изменения:
-
nil больше не вызывает nil.to_a, что согласуется с поведением **. -
IO.select теперь принимает Float::INFINITY в качестве аргумента таймаута. -
File::Stat#birthtime теперь работает в Linux через системный вызов statx, если это поддерживается ядром и файловой системой. -
Socket.tcp получил ключевой аргумент open_timeout. - RJIT удалён, остались только YJIT и ZJIT.
- Юникод обновлён до версии 17.0.
- В Windows прекращена поддержка версий MSVC старше 14.0 (
_MSC_VER 1900). Для работы с Ruby 4 потребуется Visual Studio 2015 или более поздняя версия. В целом, Ruby 4.0 закладывает основу для будущих улучшений, экспериментальных функций и развития параллельного программирования. При этом в большинстве случаев обновление должно пройти гладко, так как нет крупных ломающих изменений.
https://www.ruby-lang.org/en/news/2025/12/25/ruby-4-0-0-released/
Ruby Programming Language
Ruby 4.0.0 Released | Ruby
We are pleased to announce the release of Ruby 4.0.0.Ruby 4.0 introduces “Ruby Box” and “ZJIT”, and adds many improvements.
👍9🥱4❤3🤝2🤮1
Лучшие практики при построении REST API
(продолжение предыдущего поста)
1. Версионирование API (API Versioning)
- URL-based Versioning: версия API указывается в URL-пути, например:
Это позволяет клиентам легко переключаться между версиями.
- Query Parameter Versioning: версия задаётся через параметры запроса:
Подходит для постепенного внедрения изменений без изменения URL.
2. Стандартные коды ошибок (Standard Error Codes)
- Используйте общепринятые HTTP-коды ответов:
- 2ХХ (успех): 200 OK, 201 Created, 202 Accepted, 204 No Content.
- 4ХХ (ошибки клиента): 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict.
- 5ХХ (ошибки сервера): 500 Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout.
- Это упрощает обработку ошибок на стороне клиента.
3. Именования ресурсов (Noun-Based Resource Names)
- Используйте существительные для именования конечных точек (endpoints), а не глаголы.
Пример:
- Операции (
-
-
-
-
4. Идемпотентность (Idempotency)
- Идемпотентные методы (GET, HEAD, PUT, DELETE): многократное выполнение запроса даёт тот же результат, что и однократное. Это важно для устойчивости к сетевым сбоям.
- Неидемпотентные методы (POST, PATCH): повторные запросы могут привести к разным результатам (например, создание нескольких записей).
- Для обеспечения идемпотентности используйте Idempotency Key — уникальный ключ в запросе, который сервер сохраняет для предотвращения дублирования операций.
5. Пагинация (Pagination)
- Используйте offset pagination для разбиения больших наборов данных на страницы.
Пример:
-
-
- Это снижает нагрузку на сервер и ускоряет обработку запросов.
6. Безопасность (Security)
- Применяйте JWT (JSON Web Tokens) для аутентификации и авторизации:
- Header: содержит алгоритм шифрования (например,
- Payload: данные пользователя (ID, роль, время истечения токена и др.).
- Signature: подпись токена, созданная с помощью секретного ключа.
- Используйте HTTPS для защиты передачи данных.
7. Реализация (Implementation)
- Клиент-серверный обмен: клиент отправляет запросы, сервер обрабатывает их и взаимодействует с базой данных.
- Redis: используйте для кэширования часто запрашиваемых данных, что ускоряет отклик API.
- База данных: храните основные данные приложения.
8. Структура запросов и ответов
- Соблюдайте чёткую структуру запросов и ответов, используйте JSON для передачи данных.
- Ответы должны содержать понятные сообщения об ошибках и метаданные (например, статус операции).
9. Использование HTTP-методов
- Выбирайте HTTP-метод в зависимости от операции:
-
-
-
-
-
10. Документирование API
- Документируйте все эндпоинты, методы, параметры запросов и ответов, коды ошибок. Это облегчает использование API разработчиками.
(продолжение предыдущего поста)
1. Версионирование API (API Versioning)
- URL-based Versioning: версия API указывается в URL-пути, например:
https://api.example.com/v1/users (Version 1), https://api.example.com/v2/users (Version 2). Это позволяет клиентам легко переключаться между версиями.
- Query Parameter Versioning: версия задаётся через параметры запроса:
https://api.example.com/users?version=1 (Version 1), https://api.example.com/users?version=2 (Version 2). Подходит для постепенного внедрения изменений без изменения URL.
2. Стандартные коды ошибок (Standard Error Codes)
- Используйте общепринятые HTTP-коды ответов:
- 2ХХ (успех): 200 OK, 201 Created, 202 Accepted, 204 No Content.
- 4ХХ (ошибки клиента): 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict.
- 5ХХ (ошибки сервера): 500 Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout.
- Это упрощает обработку ошибок на стороне клиента.
3. Именования ресурсов (Noun-Based Resource Names)
- Используйте существительные для именования конечных точек (endpoints), а не глаголы.
Пример:
/api/products вместо /api/createProduct.- Операции (
Create, Read, Update, Delete) реализуются через HTTP-методы: -
POST — создание ресурса; -
GET — чтение ресурса; -
PUT — обновление ресурса; -
DELETE — удаление ресурса.4. Идемпотентность (Idempotency)
- Идемпотентные методы (GET, HEAD, PUT, DELETE): многократное выполнение запроса даёт тот же результат, что и однократное. Это важно для устойчивости к сетевым сбоям.
- Неидемпотентные методы (POST, PATCH): повторные запросы могут привести к разным результатам (например, создание нескольких записей).
- Для обеспечения идемпотентности используйте Idempotency Key — уникальный ключ в запросе, который сервер сохраняет для предотвращения дублирования операций.
5. Пагинация (Pagination)
- Используйте offset pagination для разбиения больших наборов данных на страницы.
Пример:
-
offset = 0, limit = 3 — первая страница (Page 1); -
offset = 3, limit = 3 — вторая страница (Page 2).- Это снижает нагрузку на сервер и ускоряет обработку запросов.
6. Безопасность (Security)
- Применяйте JWT (JSON Web Tokens) для аутентификации и авторизации:
- Header: содержит алгоритм шифрования (например,
HS256) и тип токена (JWT).- Payload: данные пользователя (ID, роль, время истечения токена и др.).
- Signature: подпись токена, созданная с помощью секретного ключа.
- Используйте HTTPS для защиты передачи данных.
7. Реализация (Implementation)
- Клиент-серверный обмен: клиент отправляет запросы, сервер обрабатывает их и взаимодействует с базой данных.
- Redis: используйте для кэширования часто запрашиваемых данных, что ускоряет отклик API.
- База данных: храните основные данные приложения.
8. Структура запросов и ответов
- Соблюдайте чёткую структуру запросов и ответов, используйте JSON для передачи данных.
- Ответы должны содержать понятные сообщения об ошибках и метаданные (например, статус операции).
9. Использование HTTP-методов
- Выбирайте HTTP-метод в зависимости от операции:
-
GET — для получения данных (идемпотентен);-
POST — для создания новых ресурсов (не идемпотентен);-
PUT — для полного обновления ресурса (идемпотентен);-
PATCH — для частичного обновления ресурса (не идемпотентен);-
DELETE — для удаления ресурса.10. Документирование API
- Документируйте все эндпоинты, методы, параметры запросов и ответов, коды ошибок. Это облегчает использование API разработчиками.
❤8👍3🤝2