Forwarded from Библиотека Go-разработчика | Golang
Если вы работали с Go и вам нужно было вызвать C-библиотеку, то вы наверняка сталкивались с Cgo.
Cgo работает, но тянет за собой целый набор проблем. Нужен C-компилятор на каждой целевой платформе. Кросс-компиляция превращается в боль. Сборка замедляется. Бинарники раздуваются.
purego решает всё это, позволяя вызывать C-функции из чистого Go.Откуда взялся проект
Библиотека выросла из игрового движка Ebitengine. Его авторы портировали движок на чистый Go для Windows, что позволило кросс-компилировать на Windows с любой ОС одной командой
GOOS=windows. purego родился, чтобы принести тот же подход на macOS, Linux и другие платформы.Что даёт purego
Без Cgo отпадает необходимость в C-компиляторе. Вы можете собирать проект под другую платформу, просто задав
GOOS и GOARCH. Сборка кешируется целиком как обычный Go-проект и работает быстрее. Бинарники становятся меньше, потому что Cgo генерирует обёртку на C для каждого вызова, а purego этого не делает.Ещё
purego умеет загружать символы из shared-библиотек в рантайме. Это можно использовать как систему плагинов или для FFI-вызовов в библиотеки на других языках, скомпилированные в .so / .dylib / .dll.purego работает и при CGO_ENABLED=1. Это значит, что можно портировать проект с Cgo на purego постепенно, не переписывая всё разом.Как это выглядит в коде
API минимальный. Вы открываете библиотеку через
Dlopen, затем регистрируете Go-функцию, которая будет вызывать C:package main
import (
"fmt"
"runtime"
"github.com/ebitengine/purego"
)
func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}
func main() {
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
puts("Calling C from Go without Cgo!")
}
Обратите внимание на
RegisterLibFunc. Вы объявляете переменную с нужной Go-сигнатурой, а purego привязывает её к C-функции по имени. Никаких // #cgo директив, никаких .h файлов.Когда стоит использовать
purego подходит, если вам нужно вызывать C-библиотеку из Go и при этом важна простота сборки и кросс-компиляция. Типичные сценарии — работа с системными библиотеками, графические движки, аудио, нативные SDK.Если ваш проект уже плотно завязан на Cgo и работает на одной платформе, смысла переезжать может не быть. Но если вы начинаете новый проект или хотите избавиться от зависимости на C-тулчейн,
purego стоит попробовать.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍5❤3
😎 Vibe hiring: почему сильные разработчики не проходят собесы, а «приятные» — проходят
Ты решил все задачи, ответил на все вопросы, а оффер получил кто-то другой. Добро пожаловать в эпоху vibe hiring — найма по ощущению, интуиции и «культурному фиту». Разбираемся, что это такое, почему это катастрофа для IT-рынка и что говорят свежие исследования 2026 года.
👉 Статья
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
Ты решил все задачи, ответил на все вопросы, а оффер получил кто-то другой. Добро пожаловать в эпоху vibe hiring — найма по ощущению, интуиции и «культурному фиту». Разбираемся, что это такое, почему это катастрофа для IT-рынка и что говорят свежие исследования 2026 года.
👉 Статья
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
👍2
🐸 Подборка вакансий для C++-разработчиков за неделю
Разработчик C++ — Офис (Калининград)
C++ разработчик — Удалёнка
Junior C++ Developer — Офис/Гибрид (Москва)
Программист C++ — от 250 000 ₽ Офис (Санкт-Петербург)
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#вакансии
Разработчик C++ — Офис (Калининград)
C++ разработчик — Удалёнка
Junior C++ Developer — Офис/Гибрид (Москва)
Программист C++ — от 250 000 ₽ Офис (Санкт-Петербург)
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#вакансии
👍1😁1
Forwarded from Библиотека задач по C++ | тесты, код, задания
Этот код содержит баг. Необходимо найди его:
#include <ranges>
#include <vector>
#include <iostream>
#include <algorithm>
int main() {
std::vector<int> vec = { 5, 3, 1, 4, 2 };
auto sorted_view = vec
| std::views::transform([](int x) { return x; });
std::ranges::sort(sorted_view);
for (auto v : sorted_view) {
std::cout << v << " ";
}
}
Подсказка:
Отсортируется ли
vec? Если нет — какая ошибка компиляции и почему?📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁2
📰 Свеженькое из мира C++
Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и интересных проектах в мире C++.
😎 Интересное:
• Hello World в 2 МБ — даже простые программы весят сейчас мегабайты, разбираем почему
• Reflection в C++26 — два оператора, которые меняют правила игры
• Вызов C-функций из Go без Cgo — альтернативный способ вызова C-функции из Go-кода
• Vibe hiring — почему сильные разработчики не проходят собесы
📙 Ranges:
• Комбинаторы: views::zip и views::enumerate
🔹📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#свежак
Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и интересных проектах в мире C++.
😎 Интересное:
• Hello World в 2 МБ — даже простые программы весят сейчас мегабайты, разбираем почему
• Reflection в C++26 — два оператора, которые меняют правила игры
• Вызов C-функций из Go без Cgo — альтернативный способ вызова C-функции из Go-кода
• Vibe hiring — почему сильные разработчики не проходят собесы
📙 Ranges:
• Комбинаторы: views::zip и views::enumerate
🔹📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#свежак
😁2
🧹 Сколько мусора в ваших #include?
В больших C++-проектах заголовки превращаются в паутину неявных зависимостей. Один рефакторинг — и всё сыплется, потому что кто-то полагался на транзитивный include.
• IWYU — инструмент на базе Clang, который анализирует, какие заголовки реально используются в каждом .cc/.cpp-файле, а какие тянутся впустую
• Удаление лишних include сокращает время компиляции
• Инструмент умеет подставлять forward declarations вместо полных include, что дополнительно режет зависимости
• Актуальная версия 0.26 совместима с Clang 22. Проект жив, обновляется под каждый мажорный релиз LLVM
👉 Github
✏️ Используете
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
В больших C++-проектах заголовки превращаются в паутину неявных зависимостей. Один рефакторинг — и всё сыплется, потому что кто-то полагался на транзитивный include.
• IWYU — инструмент на базе Clang, который анализирует, какие заголовки реально используются в каждом .cc/.cpp-файле, а какие тянутся впустую
• Удаление лишних include сокращает время компиляции
• Инструмент умеет подставлять forward declarations вместо полных include, что дополнительно режет зависимости
• Актуальная версия 0.26 совместима с Clang 22. Проект жив, обновляется под каждый мажорный релиз LLVM
👉 Github
✏️ Используете
IWYU на своих проектах или до сих пор чистите include вручную? 👇📍 Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
👾7😁2
Forwarded from Библиотека задач по C++ | тесты, код, задания
Что произойдёт при компиляции?
Anonymous Quiz
36%
Программа выведет 12
16%
Ошибка линковки из-за дублирования символа в программе
13%
Программа выведет 11
29%
Ошибка компиляции из-за двойного определения функции
6%
Неопределённое поведение при двойном включении файла
😢3😁2🔥1
😎 Знакомьтесь с экспертом Proglib.academy: AI-архитектор Андрей Носов
Андрей — один из ключевых спикеров нашего курса AgentOps. Он выстраивает архитектуру, которая выживает в суровом проде и активно делится своим опытом.
За что его ценит IT-комьюнити:
🟣 Топ-спикер AI Conf 2026
🟣 Эксперт по GraphRAG и Knowledge Graphs
🟣 Автор «14 кругов ада для RAG»
🟣 Спикер Saint HighLoad
Андрей упаковал свои наработки в Google Colab, где можно пощупать 14 сценариев ошибок RAG и их решения:
🔗 Забрать Colab-ноутбук
На курсе Андрей отвечает за самые «мясные» блоки: RAG, оркестрацию агентов и их промышленную эксплуатацию.
Узнать больше о программе и обучении у Андрея:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Так, продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду тестить Colab Носова
Андрей — один из ключевых спикеров нашего курса AgentOps. Он выстраивает архитектуру, которая выживает в суровом проде и активно делится своим опытом.
За что его ценит IT-комьюнити:
Его доклад про мифы семантического поиска и провалы Naive RAG стал одним из самых рейтинговых на конференции.
Андрей внедряет инженерный подход в сложные системы, заменяя «слепую веру» в эмбеддинги строгой логикой графов.
Разработал уникальный набор из 14 unit-тестов, на которых ломается стандартный векторный поиск (от слепоты к отрицаниям до конфликта версий).
Регулярно выступает на крупнейших хайлоад-площадках, разбирая архитектуру отказоустойчивых ИИ-сервисов.
Андрей упаковал свои наработки в Google Colab, где можно пощупать 14 сценариев ошибок RAG и их решения:
🔗 Забрать Colab-ноутбук
На курсе Андрей отвечает за самые «мясные» блоки: RAG, оркестрацию агентов и их промышленную эксплуатацию.
Узнать больше о программе и обучении у Андрея:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса
Так, продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду тестить Colab Носова
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱4👍2😁2❤1🌚1
Сегодня научимся работать с вложенными — «сплющивать» диапазон диапазонов в один поток и вставлять разделители между ними.
std::vector<std::vector<int>> matrix = {{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};
// Объединяем все подвекторы в один поток
for (int x : matrix | views::join) {
std::cout << x << " "; // 1 2 3 4 5 6 7 8 9
}Классический кейс — обход всех элементов матрицы без вложенных циклов.
join работает с любым диапазоном, элементы которого сами являются диапазонами: vector<vector<T>>, vector<string>, результат views::split и т.д.std::string csv = "10,20,30";
// split разбивает → join склеивает обратно (без разделителя)
for (char c : csv | views::split(',') | views::join) {
std::cout << c; // 102030
}
views::split возвращает подиапазоны, тип которых отличается от string_view. В C++23 поведение split было пересмотрено, а прежняя версия переименована в views::lazy_split. Если работаете со строками в C++20, имейте это в виду.Это зависит от исходного диапазона:
• если внешний и внутренний диапазоны моделируют
forward_range (как vector<vector<int>>), результат join тоже будет forward_range • итераторы валидны, многопроходность гарантирована
• если оба моделируют
bidirectional_range и внутренний при этом common_range, результат может быть bidirectional_range• если внешний диапазон — всего лишь
input_range (например, поток), результат join — тоже input_range, и тогда проходить его можно только линейно, в один проходstd::vector<std::string> words = {"один", "два", "три"};
// Вставляем пробел между словами
for (char c : words | views::join_with(' ')) {
std::cout << c;
}
// один два триРазделителем может быть не только один элемент, но и целый диапазон:
std::vector<std::string> parts = {"SELECT *", "FROM users", "WHERE id = 1"};
for (char c : parts | views::join_with(std::string_view{"\n "})) {
std::cout << c;
}
// SELECT *
// FROM users
// WHERE id = 1join_with требует, чтобы тип разделителя был совместим с внутренним типом элементов. Если у вас vector<vector<int>>, разделитель — int или диапазон int, а не string. Компилятор скажет об этом длинной шаблонной ошибкой — ищите в ней range_value_t.Настоящая сила раскрывается в цепочках:
std::vector<std::vector<int>> grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
// Сплющить → оставить чётные → взять первые 3
auto result = grid
| views::join
| views::filter([](int x) { return x % 2 == 0; })
| views::take(3);
for (int x : result) {
std::cout << x << " "; // 2 4 6
}Ни одного промежуточного контейнера — всё вычисляется поэлементно.
Как и все views,
join и join_with ленивые — они не копируют внутренние диапазоны и не выделяют память. Элементы «вытягиваются» по одному при итерации. Но у этой лени есть цена: join над input_range даёт только input_range, поэтому отсортировать результат напрямую не получится — сначала материализуйте через ranges::to<vector>() (C++23).📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤1
🔥 Препроцессор C++ — наследие, от которого не сбежать
Несмотря на все усилия комитета по стандартизации,
Главная проблема — текстовая подстановка. Макрос не проверяет типы, не уважает пространства имён и может сломать код в самом неожиданном месте. Классический пример:
Современный C++ предлагает альтернативы почти для каждого сценария:
✏️ А в вашем проекте много макросов, или удалось от них почти избавиться?
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Несмотря на все усилия комитета по стандартизации,
#include и #define по-прежнему живут в каждом проекте. Препроцессор — это, по сути, отдельный язык, работающий до компиляции, и он ничего не знает о типах, областях видимости и прочих правилах C++.Главная проблема — текстовая подстановка. Макрос не проверяет типы, не уважает пространства имён и может сломать код в самом неожиданном месте. Классический пример:
#define max(a,b) ((a)>(b)?(a):(b)) — попробуйте передать туда i++, и получите двойной инкремент.Современный C++ предлагает альтернативы почти для каждого сценария:
constexpr, consteval, inline-функции, шаблоны. Но полностью убить препроцессор пока не удалось.📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7😁1
🌮 7 игр сделанных на Unigine Engine
Когда говорят «C++ игровой движок», все автоматически думают про
👉 Видео с пруфами (играми)
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
Когда говорят «C++ игровой движок», все автоматически думают про
Unreal. Но UNIGINE тоже в игре — в буквальном смысле: на нём создают не только тренажёры, но и игры. Движок поддерживает Vulkan, DX12, умеет работать с огромными открытыми мирами благодаря двойной точности координат. Малоизвестная, но интересная штука в мире C++ геймдева.👉 Видео с пруфами (играми)
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
👍7
🌍💸 Хочешь работать на зарубежную компанию из России?
Прямой найм почти умер, зато появились EOR-провайдеры. Европа уступила место ОАЭ и Сингапуру. А джуны с английским иногда находят оффер быстрее, чем сеньор на hh.ru. Пять трендов валютной удаленки, о которых стоит знать прямо сейчас.
👉 Подробнее...
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
Прямой найм почти умер, зато появились EOR-провайдеры. Европа уступила место ОАЭ и Сингапуру. А джуны с английским иногда находят оффер быстрее, чем сеньор на hh.ru. Пять трендов валютной удаленки, о которых стоит знать прямо сейчас.
👉 Подробнее...
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#буст
😁2
🔥 База по экономике токенов и кэшированию от AI Platform Lead из Bitrix24
Знакомьтесь, Сергей Нотевский. AI Platform Lead в Bitrix24.
Он один из ключевых экспертов нашего курса AgentOps. На своих лекциях он детально разбирает экономику AI-агентов, кэширование токенов, LLM-инфраструктуру и вывод генеративных систем в стабильный прод.
Мы попросили Сергея поделиться материалами для тех, кто хочет оптимизировать косты на LLM в проде. Сохраняйте методичку по prefix cache метрике, которая напрямую влияет на ваши деньги.
Как говорят создатели Manus:
🛠 Что внутри методички (комбо из 3 статей + код):
🍒 Вишенка на торте: готовый SKILL для агента, который делает ревью вашего проекта, находит анти-паттерны и предотвращает низкое попадание в кэш.
— Забрать комбо-материалы на GitHub
P.S. Если хотите послушать Сергея вживую — ловите его на конференциях Kode Waves (май), Conversations AI и Highload Spb (июнь).
🎁 Акция в честь старта продаж!
Прямо сейчас при покупке Инженерного трека вы получаете полный доступ к материалам курса «Разработка ИИ-агентов» в подарок.
👉 Забрать 2 курса по цене 1 и начать обучение
Знакомьтесь, Сергей Нотевский. AI Platform Lead в Bitrix24.
Он один из ключевых экспертов нашего курса AgentOps. На своих лекциях он детально разбирает экономику AI-агентов, кэширование токенов, LLM-инфраструктуру и вывод генеративных систем в стабильный прод.
Мы попросили Сергея поделиться материалами для тех, кто хочет оптимизировать косты на LLM в проде. Сохраняйте методичку по prefix cache метрике, которая напрямую влияет на ваши деньги.
Как говорят создатели Manus:
“KV-cache hit rate is the single most important metric for a production-stage AI agent.”
🛠 Что внутри методички (комбо из 3 статей + код):
Экономика кэширования — особенности провайдеров и как правильно считать затраты.
Частые анти-паттерны — почему ваш кэш постоянно сбрасывается и вы платите больше.
Кэш в AI-агентах — специфика работы с памятью в автономных системах.
🍒 Вишенка на торте: готовый SKILL для агента, который делает ревью вашего проекта, находит анти-паттерны и предотвращает низкое попадание в кэш.
— Забрать комбо-материалы на GitHub
P.S. Если хотите послушать Сергея вживую — ловите его на конференциях Kode Waves (май), Conversations AI и Highload Spb (июнь).
🎁 Акция в честь старта продаж!
👉 Забрать 2 курса по цене 1 и начать обучение
❤1😁1🥱1
В прошлый раз мы разобрали views::join и views::join_with — «сплющивание» вложенных диапазонов. Сегодня — подборка адаптеров, которые пригождаются постоянно, но о которых часто забывают.
std::vector<int> v = {1, 2, 3, 4, 5};
for (int x : v | views::reverse) {
std::cout << x << " "; // 5 4 3 2 1
}bidirectional_range. Например, views::filter моделирует bidirectional_range, только если исходный диапазон сам bidirectional_range и common_range — так что для vector, deque или list цепочка views::filter(...) | views::reverse работает, а для forward_list или istream_view — нет.std::map<std::string, int> ages = {{"Алиса", 30}, {"Борис", 25}};
for (const auto& name : ages | views::keys) {
std::cout << name << "\n"; // Алиса, Борис
}
for (int age : ages | views::values) {
std::cout << age << "\n"; // 30, 25
}Под капотом
views::keys — это views::elements<0>, а views::values — views::elements<1>. Работает с любым диапазоном, элементы которого моделируют std::pair или std::tuple-подобный тип.std::vector<std::tuple<int, std::string, double>> records = {
{1, "Alice", 3.14},
{2, "Bob", 2.71},
};
// Берём только строки (индекс 1)
for (const auto& s : records | views::elements<1>) {
std::cout << s << "\n"; // Alice, Bob
}Обобщённая версия
keys/values — извлекает элемент с индексом N из каждого кортежа. Индекс задаётся на этапе компиляции, поэтому выход за границы — ошибка компиляции, а не UB.std::vector<int> v = {10, 20, 30, 40, 50};
auto it = v.begin() + 1; // указывает на 20
// 3 элемента начиная с позиции 1
auto three = views::counted(it, 3);
// 20, 30, 40В отличие от
views::take, который работает с диапазоном, counted принимает итератор + количество. Это незаменимо, когда у вас «голый» итератор без парного end — например, указатель указатель на элемент C-массива или результат std::find.it + n не выходит за пределы, лежит на вас — проверки в рантайме нет.std::vector<int> v = {1, 2, 3};
// views::all явно создаёт view из контейнера
auto all_view = views::all(v);
// Это полезно при передаче в функции, ожидающие viewЗачем нужен, если
| и так оборачивает? Бывает полезно при передаче контейнера в функцию, которая принимает viewable_range, или для хранения view в переменной без auto&&. На практике views::all вызывается неявно почти в каждой цепочке — но иногда явный вызов делает код яснее.Многие «классические» алгоритмы и конструкторы контейнеров ожидают, что
begin() и end() возвращают один и тот же тип. У ленивых view это часто не так — end() может вернуть sentinel, а не итератор.auto view = some_range | views::filter(...);
// Если нужно передать в старый алгоритм, требующий итераторов одного типа:
auto common_view = view | views::common;
std::copy(common_view.begin(), common_view.end(), output);
common_range, адаптер ничего не делает — просто пробрасывает как есть. Накладных расходов в этом случае ноль.std::map<std::string, std::vector<int>> data = {
{"alpha", {1, 2, 3}},
{"beta", {4, 5}},
{"gamma", {6, 7, 8, 9}},
};
// Все значения → сплющить → обратный порядок → первые 4
auto result = data
| views::values
| views::join
| views::reverse
| views::take(4);
for (int x : result) {
std::cout << x << " "; // 9 8 7 6
}Ни одного промежуточного контейнера — каждый элемент протягивается через всю цепочку лениво, по требованию.
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2
🐾 Почему std::this_thread::sleep_for не гарантирует точную паузу?
Если думал, что
Когда ты вызываешь
⚡️ На Linux гранулярность таймера по умолчанию — около 1–4 мс (зависит от CONFIG_HZ). На Windows — исторически 15.6 мс, если не вызвать timeBeginPeriod(1)
💡 Если нужна точность ниже миллисекунды — ОС-пауза не подойдёт. Для таких задач используют spin-wait с
🐸 Учитывай это при реализации любого setPause-подобного механизма в
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
Если думал, что
sleep_for(100ms) остановит поток ровно на 100 мс, то это не так. На деле — это минимальное время ожидания, не точное.Когда ты вызываешь
std::this_thread::sleep_for, происходит следующее: поток переводится в состояние WAITING в планировщике ОС. Ядро ставит таймер и убирает поток из очереди на исполнение. Когда таймер срабатывает, поток не просыпается мгновенно — он попадает обратно в ready queue и ждёт, пока планировщик выделит ему квант времени.auto start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto elapsed = std::chrono::steady_clock::now() - start;
// elapsed может быть 102ms, 115ms, даже 130ms
⚡️ На Linux гранулярность таймера по умолчанию — около 1–4 мс (зависит от CONFIG_HZ). На Windows — исторически 15.6 мс, если не вызвать timeBeginPeriod(1)
💡 Если нужна точность ниже миллисекунды — ОС-пауза не подойдёт. Для таких задач используют spin-wait с
std::chrono::high_resolution_clock, жертвуя CPU ради точности.🐸 Учитывай это при реализации любого setPause-подобного механизма в
game loop или real-time системах.📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
👍7