Каждый найдет что-то по душе:
1202 ГБ — Python
1811 ГБ — Frontend
1100 ГБ — C / C++ / C#
804 ГБ — Java
411 ГБ — SQL & БД
309 ГБ — DevOps
998 ГБ — ИБ & Хакинг
773 ГБ — Kotlin / Swift
189 ГБ — PHP
201 ГБ — GoLang
170 ГБ — Rust
167 ГБ — QA / Тестирование
310 ГБ — 1C + Лицензии
495 ГБ — Машинное обучение
704 ГБ — Аналитика Данных
991 ГБ — Дизайн
Материалы в закрепе, постоянно пополняются👆🏻
Please open Telegram to view this post
VIEW IN TELEGRAM
👎9
Сортируем контейнер через std::ranges::sort!
Допустим, есть вектор чисел, и нужно отсортировать его по возрастанию.
Раньше обычно писали так:
Работает, но приходится каждый раз передавать пару итераторов.
В C++20 можно использовать ranges-версию:
Теперь алгоритм принимает контейнер целиком.
После сортировки получим:
Если нужно отсортировать объекты по полю, можно использовать projection:
Здесь сортировка идёт не по всему объекту, а по полю
Это удобно для рейтингов, таблиц лидеров, списков товаров, отчётов и любых коллекций, где нужно быстро упорядочить данные.
📣 C++ Ready | #практика
Допустим, есть вектор чисел, и нужно отсортировать его по возрастанию.
std::vector<int> nums = {4, 1, 7, 3};Раньше обычно писали так:
std::sort(nums.begin(), nums.end());
Работает, но приходится каждый раз передавать пару итераторов.
В C++20 можно использовать ranges-версию:
std::ranges::sort(nums);
Теперь алгоритм принимает контейнер целиком.
После сортировки получим:
1 3 4 7
Если нужно отсортировать объекты по полю, можно использовать projection:
std::ranges::sort(users, {}, &User::score);Здесь сортировка идёт не по всему объекту, а по полю
score.Это удобно для рейтингов, таблиц лидеров, списков товаров, отчётов и любых коллекций, где нужно быстро упорядочить данные.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥7❤3
Не копируй элементы в цикле, если их можно читать по ссылке!
В C++ range-based for часто пишут так:
Для int или char это нормально.
Но если внутри лежат строки, структуры, объекты или большие классы, каждый элемент будет копироваться.
Например:
Если User тяжёлый, такой цикл создаёт лишние копии.
Когда нужно только читать элементы, лучше использовать const auto&:
Так объект не копируется, а код всё равно не может случайно его изменить.
Если элемент нужно менять тогда используют обычную ссылку:
А если нужен отдельный независимый объект, тогда копия через auto как раз уместна.
📣 C++ Ready | #совет
В C++ range-based for часто пишут так:
for (auto x : items) {
use(x);
}Для int или char это нормально.
Но если внутри лежат строки, структуры, объекты или большие классы, каждый элемент будет копироваться.
Например:
for (auto user : users) {
std::cout << user.name << '\n';
}Если User тяжёлый, такой цикл создаёт лишние копии.
Когда нужно только читать элементы, лучше использовать const auto&:
for (const auto& user : users) {
std::cout << user.name << '\n';
}Так объект не копируется, а код всё равно не может случайно его изменить.
Если элемент нужно менять тогда используют обычную ссылку:
for (auto& user : users) {
user.active = true;
}А если нужен отдельный независимый объект, тогда копия через auto как раз уместна.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍8🔥5😁2
Почему std::string_view может неожиданно превратиться в висячую ссылку?
std::string_view не хранит собственную строку. Он содержит только ссылку на уже существующие символы.
Поэтому возвращать view на локальный std::string опасно:
После выхода из функции name уничтожается, а результат указывает в освобождённую память.
Если функция создаёт новую строку, возвращай std::string:
view также может стать недействительным после изменения исходной строки:
При расширении text может получить новый буфер, а view останется связан со старым.
Безопасный вариант будет использовать данные с достаточным временем жизни:
Строковый литерал существует до завершения программы, поэтому такой view остаётся корректным.
📣 C++ Ready | #совет
std::string_view не хранит собственную строку. Он содержит только ссылку на уже существующие символы.
Поэтому возвращать view на локальный std::string опасно:
std::string_view make_name() {
std::string name = "Ready";
return name;
}После выхода из функции name уничтожается, а результат указывает в освобождённую память.
Если функция создаёт новую строку, возвращай std::string:
std::string make_name() {
return "Ready";
}view также может стать недействительным после изменения исходной строки:
std::string text = "C++";
std::string_view view = text;
text += std::string(100, '!');
При расширении text может получить новый буфер, а view останется связан со старым.
Безопасный вариант будет использовать данные с достаточным временем жизни:
constexpr std::string_view channel = "C++ Ready";
std::cout << channel;
Строковый литерал существует до завершения программы, поэтому такой view остаётся корректным.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍6❤4👎1
This media is not supported in your browser
VIEW IN TELEGRAM
Это набор рекомендаций по современному C++, который помогает писать более безопасный, понятный и поддерживаемый код. Здесь собраны практические правила по работе с памятью, классами, функциями, шаблонами, ошибками и архитектурой.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15❤9👍6
Разработчики из Anthropic обновили и структурировали масштабный хаб готовых запросов для своей языковой модели. База создана для того, чтобы пользователи могли выжать максимум из Claude при решении прикладных и технических задач, не тратя время на самостоятельный подбор формулировок.
🟦 Для безопасности: готовые конструкции для проверки кода на уязвимости и анализа граничных условий работы алгоритмов.
🟦 Для разработчиков: шаблоны для глубокого ревью кода, автоматического поиска багов, рефакторинга, написания юнит-тестов и проектирования архитектуры.
🟦 Для автоматизации и менеджмента: промпты под стратегическое планирование, парсинг неструктурированных данных, генерацию технической документации и выстраивание логики для ИИ-агентов.
Каждый шаблон снабжен подробным разбором: авторы пошагово объясняют, почему выбрана именно такая структура запроса, как модель интерпретирует переменные и как правильно передавать контекст. Поскольку библиотека официальная, все промпты оптимизированы под особенности контекстного окна и логику мышления последних моделей семейства Claude.
Нейросети отлично автоматизируют рутину и помогают искать уязвимости, но управлять ими может только тот, кто понимает саму базу и суть киберугроз.
Если вы хотите заложить мощный фундамент начните с нашего бесплатного курса (его прошли уже 1108 человек!).
🟦 Разберетесь, как работают кибератаки и как грамотно защитить свои данные.
🟦 Познакомитесь с направлениями и профессиями в кибербезопасности, чтобы выбрать свой трек.
🟦 Получите скидку, если решите продолжить обучение в CyberYozh Academy.
👉 Начните бесплатно прямо сейчас
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥1
Измеряем время выполнения блока кода на C++!
Создадим небольшой RAII-таймер. Он начнёт измерение при создании и автоматически покажет результат при выходе из области видимости.
Сохраним название операции и время запуска:
Добавим конструктор:
В деструкторе вычислим прошедшее время:
Остаётся вывести результат и закрыть класс:
Теперь измерим сортировку:
После выхода из блока деструктор вызовется автоматически:
steady_clock подходит для измерения интервалов, потому что не зависит от перевода системных часов.
📣 C++ Ready | #практика
Создадим небольшой RAII-таймер. Он начнёт измерение при создании и автоматически покажет результат при выходе из области видимости.
Сохраним название операции и время запуска:
class ScopeTimer {
std::string name_;
std::chrono::steady_clock::time_point start_;Добавим конструктор:
public:
explicit ScopeTimer(std::string name)
: name_(std::move(name)),
start_(std::chrono::steady_clock::now()) {}
В деструкторе вычислим прошедшее время:
ScopeTimer() {
const auto elapsed =
std::chrono::steady_clock::now() - start_;
const auto microseconds =
std::chrono::duration_cast<
std::chrono::microseconds
>(elapsed);Остаётся вывести результат и закрыть класс:
std::cout << name_ << ": "
<< microseconds.count()
<< " us\n";
}
};
Теперь измерим сортировку:
{
ScopeTimer timer("sorting");
std::ranges::sort(values);
}После выхода из блока деструктор вызовется автоматически:
sorting: 1842 us
steady_clock подходит для измерения интервалов, потому что не зависит от перевода системных часов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥7❤3
Шпаргалка по форматированию вывода в C++!
Например, {:.2f} оставляет два знака после запятой, {:08} дополняет число нулями, а {:x} выводит его в шестнадцатеричном формате.
На картинке синтаксис библиотеки {fmt}: позиционные и именованные аргументы, выравнивание, ширина, точность, системы счисления, строки, указатели, диапазоны и кортежи.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, {:.2f} оставляет два знака после запятой, {:08} дополняет число нулями, а {:x} выводит его в шестнадцатеричном формате.
На картинке синтаксис библиотеки {fmt}: позиционные и именованные аргументы, выравнивание, ширина, точность, системы счисления, строки, указатели, диапазоны и кортежи.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤6🔥6
Почему чтение через map[key] может изменить контейнер?
Обращение через квадратные скобки выглядит как обычное получение значения:
Но если ключа "api" ещё нет, operator[] автоматически создаст его и добавит значение по умолчанию.
Для int таким значением будет 0:
Получается, что код только читал значение, но размер контейнера изменился.
Если нужно найти ключ без вставки, используйте find():
Начиная с C++20 наличие ключа можно проверить через contains():
at() не создаёт новый элемент. Если ключ отсутствует, метод выбросит std::out_of_range.
При подсчёте событий поведение operator[], наоборот, очень удобно:
Используйте map[key], когда автоматическая вставка допустима. Для чтения без изменения контейнера выбирайте find(), contains() или at().
📣 C++ Ready | #совет
Обращение через квадратные скобки выглядит как обычное получение значения:
std::cout << hits["api"];
Но если ключа "api" ещё нет, operator[] автоматически создаст его и добавит значение по умолчанию.
Для int таким значением будет 0:
std::map<std::string, int> hits;
std::cout << hits["api"]; // 0
std::cout << hits.size(); // 1
Получается, что код только читал значение, но размер контейнера изменился.
Если нужно найти ключ без вставки, используйте find():
auto it = hits.find("api");
if (it != hits.end()) {
std::cout << it->second;
}Начиная с C++20 наличие ключа можно проверить через contains():
if (hits.contains("api")) {
std::cout << hits.at("api");
}at() не создаёт новый элемент. Если ключ отсутствует, метод выбросит std::out_of_range.
При подсчёте событий поведение operator[], наоборот, очень удобно:
++hits["api"];
++hits["api"];
std::cout << hits["api"]; // 2
Используйте map[key], когда автоматическая вставка допустима. Для чтения без изменения контейнера выбирайте find(), contains() или at().
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥3
Современный C++23 на компьютере с Windows 95!
В этой статье:
• Как получить совместимый 32-битный код современным компилятором
• Зачем объектные файлы передаются старому линкеру Visual C++
• Как заменить недоступные части стандартной библиотеки и работать через WinAPI
📣 C++ Ready | #статья
В этой статье:
• Как получить совместимый 32-битный код современным компилятором
• Зачем объектные файлы передаются старому линкеру Visual C++
• Как заменить недоступные части стандартной библиотеки и работать через WinAPI
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😁4❤2🔥1
IT мероприятия 🤘
Всё самое интересное для карьеры в IT: митапы, хакатоны, конференции, стажировки и обучение.
Подписывайся🤘
1. Москва
2. Санкт-Петербург
3. Для стажеров и студентов
Всё самое интересное для карьеры в IT: митапы, хакатоны, конференции, стажировки и обучение.
Подписывайся
1. Москва
2. Санкт-Петербург
3. Для стажеров и студентов
Please open Telegram to view this post
VIEW IN TELEGRAM
std::string_view не владеет строкой и в этом легко ошибиться!
Поэтому такой код опасен:
Если
Безопасный вариант сначала сохранить строку:
Теперь
Такой метод принимает строковые литералы,
А вот возвращать представление локальной строки нельзя:
После выхода из функции
📣 C++ Ready | #совет
std::string_view хранит только указатель на символы и их количество. Он не копирует текст и не продлевает время жизни исходной строки.Поэтому такой код опасен:
std::string_view name = make_name();
Если
make_name() возвращает std::string, временная строка уничтожается в конце выражения. После этого name продолжает указывать на уже недействительную память.Безопасный вариант сначала сохранить строку:
std::string name = make_name();
std::string_view view = name;
Теперь
view можно использовать, пока существует name и операции со строкой не сделали указатель недействительным.string_view хорошо подходит для параметров функций, которые только читают текст:void print_name(std::string_view name) {
std::cout << name << '\n';
}Такой метод принимает строковые литералы,
std::string и другие непрерывные последовательности символов без лишнего копирования:std::string user = "Alex";
print_name(user);
print_name("Admin");
А вот возвращать представление локальной строки нельзя:
std::string_view get_status() {
std::string status = "ready";
return status;
}После выхода из функции
status уничтожается, а возвращённый string_view становится висячим.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤5👍3
Интересный практический проект, собственная игра на C++ для портативной ретроконсоли!
В этой статье:
• Как организовать структуру небольшого игрового проекта
• Как устроить главный игровой цикл и переключение состояний
• Как разделить стартовый экран, игровой процесс и завершение игры
• Как собрать клон Google Dino и запустить его на реальном устройстве
Хороший способ посмотреть, как обычные классы, состояния и игровой цикл превращаются в законченную работающую игру.
📣 C++ Ready | #статья
В этой статье:
• Как организовать структуру небольшого игрового проекта
• Как устроить главный игровой цикл и переключение состояний
• Как разделить стартовый экран, игровой процесс и завершение игры
• Как собрать клон Google Dino и запустить его на реальном устройстве
Хороший способ посмотреть, как обычные классы, состояния и игровой цикл превращаются в законченную работающую игру.
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍6🔥3
Как безопасно удалять элементы из контейнера в C++20?
Частая ошибка удалять элементы прямо внутри range-for:
Проблема в том, что обход и изменение контейнера легко приводят к пропуску элементов, инвалидированным итераторам или слишком шумному коду.
В C++20 для этого есть std::erase_if:
После этого в vector останутся только нужные значения:
То же самое удобно работает и с ассоциативными контейнерами:
Здесь удалятся записи, где значение равно нулю, а код останется коротким и читаемым.
📣 C++ Ready | #совет
Частая ошибка удалять элементы прямо внутри range-for:
for (int x : values) {
if (x < 0) {
// удалить x?
}
}Проблема в том, что обход и изменение контейнера легко приводят к пропуску элементов, инвалидированным итераторам или слишком шумному коду.
В C++20 для этого есть std::erase_if:
std::vector<int> values{5, -1, 7, -3};
std::erase_if(values, [](int x) {
return x < 0;
});После этого в vector останутся только нужные значения:
// values: 5, 7
То же самое удобно работает и с ассоциативными контейнерами:
std::map<std::string, int> scores{
{"ann", 10},
{"bob", 0},
{"kim", 7}
};
std::erase_if(scores, [](const auto& item) {
return item.second == 0;
});Здесь удалятся записи, где значение равно нулю, а код останется коротким и читаемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥5👍3
Очень интересная статья о том, как автор пытался воссоздать Minecraft на C++ и Vulkan за одну неделю!
В этой статье:
• Как устроена идея voxel-мира и генерации чанков
• Почему Vulkan требует аккуратной работы с рендерингом и ресурсами
• Как маленький прототип постепенно превращается в собственный игровой движок
📣 C++ Ready | #статья
В этой статье:
• Как устроена идея voxel-мира и генерации чанков
• Почему Vulkan требует аккуратной работы с рендерингом и ресурсами
• Как маленький прототип постепенно превращается в собственный игровой движок
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥7👍5
Напоминалка по алгоритмам стандартной библиотеки C++!
Например, std::find_if помогает найти элемент по условию, std::sort сортирует диапазон, а std::transform удобно применять для преобразования значений без ручного цикла.
На картинке шпаргалка по STL-алгоритмам: поиск, сравнение диапазонов, сортировка, partition, rotate, copy, transform, remove, unique и числовые алгоритмы из <numeric>.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, std::find_if помогает найти элемент по условию, std::sort сортирует диапазон, а std::transform удобно применять для преобразования значений без ручного цикла.
На картинке шпаргалка по STL-алгоритмам: поиск, сравнение диапазонов, сортировка, partition, rotate, copy, transform, remove, unique и числовые алгоритмы из <numeric>.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤5👍3
Опа, тут бывший сеньор одного из IT-отделов Яндекса Игорь Никитин выкатил целый канал про Python — и это лучшее, что есть в рунете по теме.
Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.
Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.
Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
👎6👍1
Собираем маленький scope guard!
Иногда нужно выполнить действие при выходе из функции: закрыть временный режим, вернуть флаг обратно, удалить временный файл или откатить локальное состояние.
Писать cleanup руками в каждом return неудобно:
Если return станет больше, легко забыть один из вызовов disable().
Сделаем небольшой scope guard:
В деструкторе он выполнит переданную функцию:
Запретим копирование, чтобы cleanup не вызвался дважды:
Поля класса:
Теперь очистка привязана к области видимости:
disable вызовется и при обычном завершении, и при раннем return.
Тот же подход удобен для временных файлов:
И для восстановления старого значения:
Scope guard это простой способ сделать cleanup надёжным. Код меньше зависит от того, сколько return появится внутри функции.
📣 C++ Ready | #практика
Иногда нужно выполнить действие при выходе из функции: закрыть временный режим, вернуть флаг обратно, удалить временный файл или откатить локальное состояние.
Писать cleanup руками в каждом return неудобно:
void process() {
enable();
if (!check_input()) {
disable();
return;
}
run_job();
disable();
}Если return станет больше, легко забыть один из вызовов disable().
Сделаем небольшой scope guard:
#include <functional>
#include <utility>
class ScopeExit {
public:
explicit ScopeExit(std::function<void()> fn)
: fn_(std::move(fn)) {}
В деструкторе он выполнит переданную функцию:
~ScopeExit() {
if (fn_) {
fn_();
}
}Запретим копирование, чтобы cleanup не вызвался дважды:
ScopeExit(const ScopeExit&) = delete;
ScopeExit& operator=(const ScopeExit&) = delete;
Поля класса:
private:
std::function<void()> fn_;
};
Теперь очистка привязана к области видимости:
void process() {
enable();
ScopeExit guard([] {
disable();
});
if (!check_input()) {
return;
}
run_job();
}disable вызовется и при обычном завершении, и при раннем return.
Тот же подход удобен для временных файлов:
ScopeExit cleanup([&] {
std::filesystem::remove(path);
});И для восстановления старого значения:
bool old = config.debug;
config.debug = true;
ScopeExit restore([&] {
config.debug = old;
});
Scope guard это простой способ сделать cleanup надёжным. Код меньше зависит от того, сколько return появится внутри функции.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3🔥3