This media is not supported in your browser
VIEW IN TELEGRAM
Здесь собраны десятки CLI-инструментов, полезные bash/zsh-скрипты, практичные сниппеты и лайфхаки, которые ускоряют работу. Отличный набор для автоматизации, оптимизации и прокачки навыков работы с командной строкой.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥7👍5
SSO помогает писать быстрый код без дополнительных усилий — просто используя std::string там, где строки обычно короткие.В что важно знать:
• SSO — это оптимизация реализации, а не контракт стандарта;
• Самый большой профит — в большом количестве маленьких строк;
• Рост строки может “выключить” SSO, поэтому reserve() часто спасает.
Заключение: Используйте
std::string смело, но помните, что SSO — приятный бонус, а не гарантия.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥25❤13👍7🤝4
На картинке — краткое напоминание о ключевых нововведениях в C++17:
if constexpr, шаблоны с auto, структурные привязки, вложенные пространства имён, атрибуты [[nodiscard]], [[maybe_unused]], [[fallthrough]], сложение параметров с помощью fold-выражений, constexpr-лямбды, прямые инициализации enum.Полезный сжатый обзор для тех, кто пишет на modern C++ и хочет держать язык под контролем.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥8❤4
Почему auto иногда делает код более читаемым?
Многие боятся
Типичный пример — итераторы:
Вместо:
Смысл строки — “взяли итератор на начало”, а не “прочитай 40 символов типа”.
Ещё один сильный кейс — structured bindings в циклах по
Без
Где auto особенно уместен:
А не прятать тип лучше:
🔥 Итог: используй
📣 C++ Ready | #совет
Многие боятся
auto, потому что “не видно тип”. Но часто тип как раз мешает чтению: он длинный, шаблонный и не несёт смысла.Типичный пример — итераторы:
auto it = v.begin();
Вместо:
std::vector<std::string>::iterator it = v.begin();
Смысл строки — “взяли итератор на начало”, а не “прочитай 40 символов типа”.
Ещё один сильный кейс — structured bindings в циклах по
map:for (auto& [key, value] : m) { ... }Без
auto тут обычно появляется std::pair<const std::string, int>&, и читаемость падает.Где auto особенно уместен:
• когда тип очевиден из правой части (v.begin(), make_unique, find, size())
• когда тип слишком “шумный” и отвлекает
• когда важнее роль переменной, а не её точный тип
А не прятать тип лучше:
• когда это влияет на поведение (int vs size_t, auto vs auto&)
• когда auto может случайно сделать копию вместо ссылки
🔥 Итог: используй
auto, чтобы убрать “шум типов”, но следи за ссылками и const: часто правильнее auto& / const auto&, чем просто auto.Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥9❤5
В этой статье:
• Понять, какие блокировщики оптимизаций мешают компилятору в реальности• Увидеть, как измерять скорость через CPE и задержки• Разобраться в приёмах: инварианты, регистры, ветвления, SIMD, циклы🔊 Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥6❤4
[[likely]] и [[unlikely]]: когда они реально помогают?
Иногда хочется «подсказать» компилятору, какая ветка выполняется чаще — и получить чуть больше производительности без переписывания логики.
Для этого в C++ есть атрибуты
Пример: быстрый путь — когда всё ок, редкий — когда ошибка:
Или наоборот: редкая проверка на ошибку в начале функции:
Но важно: эти атрибуты — не «магия оптимизации». Они полезны, когда:
Хороший паттерн: помечать
🔥
📣 C++ Ready | #практика
Иногда хочется «подсказать» компилятору, какая ветка выполняется чаще — и получить чуть больше производительности без переписывания логики.
Для этого в C++ есть атрибуты
[[likely]] и [[unlikely]]: они помечают ветку как более/менее вероятную, чтобы компилятор мог лучше разложить код (например, под предсказание ветвлений).Пример: быстрый путь — когда всё ок, редкий — когда ошибка:
int parse_number(std::string_view s) {
if (s.empty()) [[unlikely]] {
return -1; // редкая ошибка
}
// основной “горячий” путь
return static_cast<int>(s[0] - '0');
}Или наоборот: редкая проверка на ошибку в начале функции:
int divide(int a, int b) {
if (b == 0) [[unlikely]] {
return 0; // обработка ошибки
}
return a / b; // обычный случай
}Но важно: эти атрибуты — не «магия оптимизации». Они полезны, когда:
• у тебя реально есть горячий код (часто вызываемый участок);
• есть ветка, которая почти никогда не выполняется (ошибка, исключительный случай);
• профилирование или здравый смысл подтверждают, что распределение сильно перекошено.
Хороший паттерн: помечать
[[unlikely]] на проверках ошибок, а основной путь оставлять без атрибутов (или ставить [[likely]] на него, если хочется подчеркнуть намерение):int handle(int fd) {
if (fd < 0) [[unlikely]] {
return -1;
}
// нормальный случай
return do_work(fd);
}[[likely]] / [[unlikely]] — это тонкая настройка: используй их точечно на редких ошибках и исключительных ветках. Если нет горячего участка — лучше не шуметь и оставить оптимизацию компилятору.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍11❤7
This media is not supported in your browser
VIEW IN TELEGRAM
Вводишь любую команду в терминале, и он по частям объясняет, что делает каждая часть. Не просто man-ка, а понятный синтакс-анализ.
Особенно кайф для тех, кто работает в
Linux/DevOps/CI среде и хочет разбираться, а не наугад копипастить из StackOverflow.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍9🤝8❤1
❤11👍5🔥3
На картинке — аккуратная
Bash Cheat Sheet, которая помогает быстро вспомнить базовые действия в терминале: как ориентироваться в файловой системе, работать с файлами и содержимым, управлять правами доступа, упаковывать и распаковывать архивы, а также следить за процессами и управлять ими. Сохрани, чтобы терминал перестал казаться магией и начал работать на тебя
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍7🔥4
RAII против goto cleanup: убираем утечки и ручную зачистку!
В “почти C”-коде на C++ часто открываешь ресурс, потом ещё один, а при ошибке нужно не забыть всё закрыть. Обычно это превращается в
Вот как это выглядит в начале: уже приходится помнить, что закрывать при неудаче:
Дальше появляется “ошибка в середине”, и чтобы не дублировать очистку, добавляют
А в конце — ручной порядок освобождения, который легко сломать правками:
В C++ это решает RAII: ресурс заворачиваем в объект, и он освобождается автоматически при выходе из области видимости.
Файл можно обернуть в
Буфер тоже делаем RAII-шным — и теперь любой ранний
🔥
📣 C++ Ready | #практика
В “почти C”-коде на C++ часто открываешь ресурс, потом ещё один, а при ошибке нужно не забыть всё закрыть. Обычно это превращается в
goto cleanup или дублирование free/fclose перед каждым return.Вот как это выглядит в начале: уже приходится помнить, что закрывать при неудаче:
FILE* f = std::fopen("data.txt", "r");
if (!f) return -1;
char* buf = (char*)std::malloc(1024);
if (!buf) { std::fclose(f); return -1; }Дальше появляется “ошибка в середине”, и чтобы не дублировать очистку, добавляют
cleanup:int rc = 0;
if (something_bad()) {
rc = -1;
goto cleanup;
}
А в конце — ручной порядок освобождения, который легко сломать правками:
cleanup:
std::free(buf);
std::fclose(f);
return rc;
В C++ это решает RAII: ресурс заворачиваем в объект, и он освобождается автоматически при выходе из области видимости.
Файл можно обернуть в
std::unique_ptr с deleter’ом:using FilePtr = std::unique_ptr<FILE, decltype(&std::fclose)>;
FilePtr f(std::fopen("data.txt", "r"), &std::fclose);
if (!f) return -1;
Буфер тоже делаем RAII-шным — и теперь любой ранний
return безопасен:auto buf = std::make_unique<char[]>(1024);
if (something_bad()) return -1;
return 0;
RAII убирает goto cleanup и ручные освобождения: добавляешь новые ветки и выходы — и не думаешь, где что закрыть.Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍7🔥6
This media is not supported in your browser
VIEW IN TELEGRAM
Если обычные видеоуроки не заходят и хочется больше практики — Scrimba решает эту задачу. Здесь обучение построено так, что ты не просто смотришь объяснение, а сразу работаешь с кодом прямо в уроке: меняешь примеры, запускаешь и смотришь результат. На платформе есть множество языков и технологий.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤9🔥7
std::move не перемещает, а “разрешает перемещать”!
Частая ошибка — думать, что
На самом деле
Реальное перемещение происходит только там, где вызывается:
• move-конструктор
• move-оператор присваивания
• или перегрузка функции, принимающая rvalue (
Поэтому строка:
не “переместила” ничего магически — она просто создала
Перемещение гарантированно случается, когда ты строишь/присваиваешь объект из rvalue:
Важный практический вывод: после
🔥 Итог: ставь
📣 C++ Ready | #совет
Частая ошибка — думать, что
std::move(x) сам переносит ресурсы и “обнуляет” объект.На самом деле
std::move — это просто приведение к rvalue-ссылке: он говорит компилятору “считай, что этот объект можно перемещать”.Реальное перемещение происходит только там, где вызывается:
• move-конструктор
• move-оператор присваивания
• или перегрузка функции, принимающая rvalue (
T&&)Поэтому строка:
auto b = std::move(a);
не “переместила” ничего магически — она просто создала
b (а вот *каким образом* — копированием или перемещением — зависит от типа и контекста).Перемещение гарантированно случается, когда ты строишь/присваиваешь объект из rvalue:
std::string c = std::move(b); // move-конструктор
Важный практический вывод: после
std::move(x) объект x остаётся валидным, но его состояние не определено (его можно переиспользовать только через присваивание или безопасные операции типа clear()/empty()/size() — в зависимости от типа).std::move там, где ты вроде бы “отдаёшь” объект (в контейнер, в return, в конструктор/присваивание) — это не перенос, а явный сигнал: “дальше мне это значение не нужно”.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍7❤5
This media is not supported in your browser
VIEW IN TELEGRAM
Сайт с огромной коллекцией задач по программированию, от самых простых до тех, что реально заставят подумать.
Учиться можно на абсолютно любом языке. Отличный способ подтянуть логику, научиться писать аккуратный код и подготовиться к собесам.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍8🔥8😁1
Поставлю себе цель: набрать более 25 тысяч подписчиков. Желаю каждому выполнить планы.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🔥11❤8😁2
Как min/max из windows.h ломают std::min/std::max?
На Windows легко словить странную ошибку компиляции в невинном месте:
Причина:
Правильный вариант — отключить эти макросы до подключения Windows-заголовков:
Если
И есть аварийный трюк, если нельзя менять include-порядок: обернуть имя в скобки — тогда макрос не сработает:
🔥 Итог: на Windows держи правило — `NOMINMAX` включён всегда, иначе стандартная библиотека будет ломаться в самых неожиданных местах.
📣 C++ Ready | #практика
На Windows легко словить странную ошибку компиляции в невинном месте:
#include <windows.h>
#include <algorithm>
auto m = std::min(a, b);
Причина:
windows.h (и некоторые связанные хедеры) могут определить макросы min/max. Тогда std::min(a, b) превращается в макро-подстановку, и начинает “ехать” всё, что выглядит как вызов функции.Правильный вариант — отключить эти макросы до подключения Windows-заголовков:
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <algorithm>
auto m = std::min(a, b);
Если
windows.h уже подключили (или его подтянула зависимость), можно убрать макросы точечно:#include <windows.h>
#undef min
#undef max
#include <algorithm>
И есть аварийный трюк, если нельзя менять include-порядок: обернуть имя в скобки — тогда макрос не сработает:
auto m = (std::min)(a, b);
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🤝9❤8