Изучаем C++. По вопросам сотрудничества: @adv_and_pr
emplace_back
Функция emplace_back используется для вставки нового элемента в конец контейнера типа std::vector или std::list.
Отличие от обычного push_back
заключается в том, что emplace_back
конструирует новый элемент прямо на месте, в то время как push_back
сначала создает временный объект, а затем перемещает его в контейнер.
Преимущества emplace_back
:
— Позволяет избежать лишних операций копирования или перемещения объектов при вставке. Объект создается сразу на месте.
— Может принимать аргументы для конструктора вставляемого объекта. У push_back
только один параметр — сам объект.
— Более эффективно для классов без определенного конструктора копирования или перемещения.
Таким образом, emplace_back
позволяет оптимизировать вставку элементов в вектор или список за счет создания объекта прямо на месте.
Это полезно при работе с классами, которые дороги в копировании/перемещении или требуют параметры для конструирования.
🚀 Отличная API-традиция! ВТБ приглашает принять участие в (уже!) третьем по счету VTB API hackathon'е!
Создайте инновационные решения вместе с ВТБ и при поддержке экспертов Платформы API, развиваемой банком!
Призовой фонд VTB API hackathon 2023 – 1,8 млн рублей!
👉 Регистрация открыта до 1 октября: https://cnrlink.com/vtbapi23sevs
К участию приглашаются специалисты со всей России: разработчики, аналитики, продакт-менеджеры, графические и UX/UI-дизайнеры, QA- и DevOps– и специалисты по информационной безопасности!
В этом году представляем сразу 3 трека:
1. Открытые API: создание приложения на основе открытых API ВТБ
2. Алгоритмы ГОСТ: создание инструмента для обеспечения безопасности синхронного и асинхронного взаимодействия с API
3. S3 CEPH: создание отказоустойчивого слоя репликации и дупликации данных между кластерами CEPH
👉 Успейте зарегистрироваться: https://cnrlink.com/vtbapi23sevs
Реклама. БАНК ВТБ (ПАО). ИНН 7702070139. erid: LjN8KEPhi
string.back
Эта функция возвращает ссылку на последний символ строки.
Она позволяет получить доступ к последнему символу строки и при необходимости изменить его.
Возвращаемое значение имеет тип символа строки, обычно char
или wchar_t
. Если строка пустая, то поведение функции неопределенно, поэтому нужно проверять, что строка не пуста, прежде чем вызывать back()
.string.back
часто используется в циклах для обработки символов строки с конца или для проверки последнего символа.
#это_база
#вопросы_с_собеседований
Что случится, если вернуть ссылку на временный объект?
Если вернуть ссылку на временный объект, созданный в стеке, то это приведет к неопределенному поведению программы.
После выхода из функции память, выделенная под временный объект, освобождается. И если где-то сохранилась ссылка на этот объект, то при попытке обратиться к нему произойдет ошибка.
#вопросы_с_собеседований
Какие методы можно вызвать из константных объектов?
Из константных объектов можно вызывать только константные методы — методы, которые помечены ключевым словом const.
Константные методы не меняют состояние объекта, а только читают данные. Они гарантируют, что работа с объектом будет безопасной.
Неконстантные же методы могут изменять состояние объекта. Их нельзя вызвать из константного объекта, чтобы избежать непреднамеренного изменения объекта.
Таким образом константность защищает объект от изменений там, где это нужно. А разделение на константные и неконстантные методы дает возможность гибко управлять доступом к данным в объекте.
Как управлять состоянием системы через события?
Event-driven архитектура — концепция программирования, которая позволяет создавать сложные приложения, используя событийно-ориентированный подход. Так создаются распределенные системы, которые легко масштабируются и обладают высокой отказоустойчивостью.
Начните изучать эту технологию на бесплатном открытом уроке «Архитектурный подход Event Driven Architecture» от OTUS: https://otus.pw/Styj/
На занятии рассмотрим:
✔️ взаимодействие сервисов на основе событий;
✔️ плюсы и минусы такого подхода;
✔️ сочетания событийного и синхронного взаимодействия;
✔️ паттерны проектирования событий;
✔️ подход Event Sourcing и CQRS.
Урок пройдёт 27 сентября в 20:00 мск в рамках курса «Microservice Architecture».
👩💻 Пройдите вступительное тестирование прямо сейчас и зарегистрируйтесь на событие: https://otus.pw/Styj/
Реклама. ООО "ОТУС ОНЛАЙН-ОБРАЗОВАНИЕ". ИНН 9705100963. erid: LjN8KUC7z
std::swapstd::swap
находится в заголовочном файле <utility>
и используется для обмена значениями двух переменных одного типа.
Функция принимает ссылки на две переменные типа T. Меняет их местами.
Работает с любыми типами данных, которые поддерживают оператор присваивания. Может быть перегружен для пользовательских типов данных.
Также стандартная библиотека С++ содержит специализированные версии swap
для контейнеров.
Часто используется вместо ручного обмена значениями с помощью третьей переменной.
#это_база
Функция value_or
Функция value_or
используется для получения значения из объекта типа std::optional
.
Класс std::optional
позволяет хранить значение или отсутствие значения.
Чтобы получить это значение из optional
, обычно используют метод value()
. Но если значения нет, это выбросит исключение.
Чтобы избежать исключения при отсутствии значения, можно воспользоваться функцией value_or
. Она принимает объект std::optional
и значение по умолчанию.
Если в optional
есть значение — возвращается оно. Если значения нет — возвращается значение по умолчанию.
Для специалистов в области искусственного интеллекта и машинного обучения 2023 год стал прорывным, и SmartDev 2023 — это отличный шанс разобраться во всех изменениях. Конференция пройдет 21 сентября в кинотеатре «Октябрь» и соберет экспертов из Сбера, VK, Яндекса, Kaspersky и многих других.
Что будет обсуждаться на конференции:
Прорыв в области AI: Как 2023 год стал переломным для прикладного применения искусственного интеллекта.
Большие языковые модели: Обсуждение текущей ситуации и возможностей для будущего.
GigaChat и Kandinsky: Два громких проекта от Сбера, которые задали новые стандарты в области AI и ML.
Стратегия и инновации: Как российский компаниям выйти на международную арену в новых реалиях. А также обсуждение глобальных технологических и экономических трендов.
Присоединяйтесь к трансляции докладов, участие бесплатное. Подробности и регистрация доступны на официальном сайте конференции.
#вопросы_с_собеседований
Какая разница между структурой и классом?
Главное отличие заключается в том, что структуры по умолчанию имеют public доступ к своим полям, в то время как классы по умолчанию имеют private доступ.
— Структуры обычно используются для простых объектных типов данных, в то время как классы — для более сложных объектов.
— Структуры копируются по значению, а классы — по ссылке. Это означает, что при копировании структуры создается новый объект, а при копировании класса копируется указатель на объект.
— Структуры не поддерживают наследование, в отличие от классов.
В целом, структуры чаще используются для простых данных, а классы — для представления более сложных сущностей и их взаимодействия.
Выбор между ними зависит от конкретной задачи и требований к программе.
Ключевое слово autoauto
— это тип вывода, который позволяет компилятору автоматически определять тип переменной на основе выражения инициализации.
Он был введен в C++11 для упрощения объявления переменных, избавляя от необходимости указывать длинные и сложные типы.
При использовании auto
тип переменной выводится компилятором во время компиляции и не может меняться во время выполнения.
Работает для любых типов данных — встроенных, пользовательских, шаблонов.
Переменная, объявленная с auto
, всегда инициализируется при объявлении.auto
полезен при работе с итераторами, с функциями возврата сложных типов, для упрощения кода.
#это_база
std::get
Функция std::get
используется для получения элемента из структуры данных по указанному индексу или ключу.
Она применяется, когда нужно получить доступ к элементу внутри контейнера, такого как массив, вектор, map и другие. При этом сам тип контейнера может быть обобщенным.std::get
позволяет абстрагироваться от конкретного типа контейнера и работать с элементами единообразно, указывая лишь индекс или ключ нужного элемента.
Это упрощает код и делает его более универсальным. Нет необходимости писать отдельный код для доступа к элементам структур.
#вопросы_с_собеседований
В чем разница между многопоточностью и асинхронностью?
Разница между многопоточностью и асинхронностью заключается в подходе к параллельному выполнению кода.
При многопоточности создаются несколько потоков управления, которые выполняются параллельно и могут разделять общие данные.
Это позволяет эффективно использовать многоядерные процессоры, но требует синхронизации доступа к общим данным с помощью мьютексов, семафоров и т. д.
Асинхронность же основана на событийной модели — код выполняется последовательно в рамках одного потока, но части кода могут приостанавливаться в ожидании каких-либо событий (например, завершения ввода-вывода).
Это позволяет избежать сложностей синхронизации, но ограничивает возможности параллелизма.
Таким образом, многопоточность эффективнее использует ресурсы процессора, а асинхронность проще в реализации и избегает проблем синхронизации.
Почленное копирование
Почленное копирование — это копирование объекта с полным копированием его внутреннего состояния.
Оно используется для корректного копирования там, где побитовое копирование оказывается неэффективным.
Почленное копирование выполняется с помощью конструктора копирования и оператора присваивания. В них для каждого поля выполняется отдельное копирование.
Для указателей и выделенной памяти почленное копирование подразумевает выделение новой памяти и копирование данных по элементам.
Почленное копирование медленнее побитового, так как требует дополнительных операций. Зато оно корректно копирует состояние объекта.
Но, зато оно помогает избежать типичных ошибок, связанных с побитовым копированием.
Чтобы включить почленное копирование в класс, нужно определить для него конструктор копирования и оператор присваивания с нужной логикой копирования.
Можно также использовать ключевое слово copy
для полей класса, чтобы компилятор автоматически сгенерировал код копирования для них.
#это_база
std::bytestd::byte
— это тип данных, представляющий собой байт, введенный в С++17.
Это тип с фиксированным размером в 1 байт, в отличие от char
, размер которого зависит от платформы. Гарантированно не имеет знака (unsigned
)
Поддерживает все операции сдвига и битовые операцииstd::byte
используется в следующих случаях:
— Для представления байтовых данных без неявных преобразований типов.
— В низкоуровневом коде, работающем с памятью, регистрами и т. д.
— В криптографии и работе с сетевыми данными.
— Для явного обозначения, что переменная содержит просто байт данных.
Преимущества std::byte
:
— Независим от платформы, в отличие от char
и uint8_t
.
— Повышает читаемость кода, явно указывая на тип "байт".
— Исключает ошибки преобразования к int
/bool
при вычислениях.
Исключение std::bad_any_cast
Исключение std::bad_any_cast выбрасывается при неудачной попытке приведения типа any к другому типу. Это происходит, когда тип, к которому производится приведение, не соответствует реальному типу объекта, хранящегося в any
.
Например, если в any
хранится объект типа int
, а мы пытаемся привести его к типу std::string
, то будет выброшено исключение bad_any_cast
.
Это исключение позволяет обнаружить ошибки при использовании any
во время выполнения программы.
Таким образом, bad_any_cast
гарантирует типобезопасность при работе с any
и указывает на то, что при приведении типов была допущена ошибка.
Чтобы избежать этого исключения, нужно проверять тип объекта в any с помощью any_cast
перед приведением типа.
void указатели
Void указатель (void*
) — это не типизированный указатель, который может указывать на объект любого типа.
Void указатели могут приводиться к любому другому типу указателей и обратно без явного преобразования.
Арифметические операции недопустимы для void указателей, так как компилятор не знает размер объекта в памяти. При их использовании нужно следить за типобезопасностью и правильностью приведений типов.
В основном void указатели используются для обобщенной работы с указателями разных типов. Например, в функциях реализующих общие алгоритмы.
#это_база
На C++ можно программировать всё: от микрокода для дефибриллятора до операционных систем. Изучите этот язык с нуля в Яндекс Практикуме.
В портфолио после курса будут реальные программы — поисковый сервер и транспортный справочник. А ещё мы поможем составить резюме и портфолио, проведём тестовые собеседования, предложим партнёрские вакансии и поможем дойти до оффера.
→ Начните учиться бесплатно
Привет! Мы в МТС активно поддерживаем ИТ-сообщество в России и запускаем всероссийскую олимпиаду по программированию с главным призом в 3 млн рублей.
Для кого? Для школьников, студентов и действующих ИТ-специалистов.
Что будет? Блок онлайн-заданий, митапы и мастер-классы, общение в закрытом Telegram-канале и финальный очный тур с программированием на скорость. Когда олимпиада завершится, мы создадим True Tech Community, где будем делиться полезными и эксклюзивными материалами для разработчиков.
А что еще? Финалистов ждет afterparty, фестиваль технологий, интерактив, квесты, карьерные стенды, где лучшие специалисты смогут получить оффер от МТС.
Регистрация уже открыта! Подробности по ссылке. Ждем тебя!
Реклама. ПАО "МТС". ИНН 7740000076. erid: LjN8KKQwJ
#вопросы_с_собеседований
Расскажите о битовых полях.
Битовые поля (bit fields) — это возможность в С++ объявить структуру или класс, в котором отдельные члены занимают указанное количество бит.
Это позволяет эффективно использовать память для хранения флагов, битовых масок и других небольших значений.
При обращении к этим полям происходят битовые операции. Можно устанавливать, сбрасывать биты, проверять их состояние.
Битовые поля позволяют гибко упаковывать данные и экономить память.
Но их использование усложняет код, делает его менее читабельным. Поэтому нужно применять с осторожностью, только когда экономия памяти критична.
#вопросы_с_собеседований
Что будет, если дважды вызвать free?
Если вызвать free два раза для одного и того же участка памяти, это приведет к неопределенному поведению программы и скорее всего к ее аварийному завершению.
При первом вызове free освобождается участок памяти и возвращается в кучу для последующего выделения.
При повторном вызове для того же участка менеджер памяти попытается освободить уже освобождённую область.
Это приведет к повреждению структур данных менеджера памяти и неопределенному поведению — от тихих ошибок вроде утечек памяти, до полного сбоя и аварийного завершения программы.
memsetmemset
используется для заполнения блока памяти одним значением байта.
Она принимает указатель на блок памяти, значение байта для заполнения и размер блока в байтах.memset
полезна для быстрого обнуления или заполнения блоков памяти.
Необходимо быть осторожным с типами данных, т. к. memset
работает на уровне байтов.
#это_база
std::any_caststd::any_cast
используется для приведения объектов типа std::any
к конкретному типу данных во время выполнения программы.
Класс std::any
может хранить данные любого типа, но при этом теряется информация о реальном типе данных.
Чтобы получить эти данные обратно в изначальный тип, и используется std::any_cast
. Он проверяет, совместим ли хранимый в std::any
объект с запрошенным целевым типом.
Если совместим — возвращает ссылку на данные нужного типа.
Например, если в std::any
был помещен объект типа int
, то с помощью std::any_cast
этот int
можно получить обратно в переменную типа int
. Аналогично для других типов данных.
#вопросы_с_собеседований
Как изменить поле класса в константном методе класса?
В константном методе класса нельзя изменить значение поля, объявленного как const.
Однако, можно изменить поле, объявленное без ключевого слова const, даже внутри const метода. Хотя это и не рекомендуется, так как нарушает идею неизменяемости объекта в константном контексте.
Чтобы все же иметь возможность модифицировать поля внутри const метода, можно объявить нужные поля как mutable. Тогда компилятор разрешит изменять эти поля, даже если вызов осуществляется на константный объект и из константного метода.
Но использование mutable стоит ограничивать, по возможности избегая. Лучше пересмотреть структуру класса, чтобы константные методы не нуждались в изменении полей.
Алгоритм find_ifFind_if
— это алгоритм из стандартной библиотеки algorithm
. Он применяется к диапазону элементов (например, контейнеру) и ищет элемент, удовлетворяющий заданному условию.
В качестве условия передается функция или функциональный объект (предикат). Предикат принимает элемент и возвращает истину, если элемент подходит.
Этот алгоритм используется, когда нужно найти объект по произвольному критерию, не только по значению.
Он более гибкий, чем find
, который ищет конкретное значение.Find_if
удобно применять с лямбда-функциями в качестве предикатов поиска.
#это_база
std::optionalstd::optional
— это класс-обертка, который может содержать значение или быть пустым.
Он используется для обозначения опционального значения.
Основное его применение — возвращать значение из функции, которое может отсутствовать. Например, при поиске элемента в контейнере, если элемент не найден, вместо исключения можно вернуть std::optional
.
Также он удобен при работе со значениями, которые могут отсутствовать, например при чтении из базы данных.
По сравнению с указателями std::optional
более выразителен — сразу видно, что значение может отсутствовать.
Кроме того, он не имеет проблем с утечками памяти и инициализацией.
🔍 Rust Journey: Хотите освоить язык программирования, который завоевывает мир?
🚀 Илон Маск, один из ведущих инноваторов нашего времени, утверждает, что за Rust будущее. А когда последний раз он ошибался в своих прогнозах? 😉
🪟Также недавно стало известно, что ядро Windows 11 переписывается на Rust.
✨ Не упустите свой шанс быть в авангарде IT-революции. Подписывайтесь на канал Rust Journey и начните свой путь в захватывающий мир Rust сегодня!
#вопросы_с_собеседований
Почему вызов container.size() перед каждой итерацией цикла является плохой практикой?
Вызов container.size() перед каждой итерацией по контейнеру не является оптимальным, так как это приводит к линейной сложности O(n).
Вместо этого лучше сохранить размер контейнера в переменную до цикла, таким образом размер вычисляется только один раз, а доступ к элементам в цикле происходит за константное время O(1).
Это позволяет избежать лишних вычислений размера на каждой итерации и улучшает производительность.
Побитовое копирование
Побитовое копирование — копирование данных из одного объекта в другой побитно, без каких-либо преобразований.
Оно используется для копирования структур и классов. Когда мы присваиваем один объект другому того же типа, происходит побитовое копирование.
Побитовое копирование быстрее обычного копирования, так как не требует вызова конструкторов и деструкторов. Но при этом копируются все данные объекта, даже те, которые не нужны.
Чтобы предотвратить побитовое копирование для класса, можно объявить конструктор копирования и оператор присваивания private
. Тогда компилятор выдаст ошибку при попытке копирования.
Также для предотвращения побитового копирования можно использовать ключевое слово delete
для этих методов.
#это_база
Паттерн Strategy
Паттерн Strategy — это паттерн проектирования, который позволяет определять семейства связанных алгоритмов и делать их взаимозаменяемыми.
Это дает возможность выбирать конкретный алгоритм во время выполнения программы.
Основная идея паттерна Strategy заключается в том, чтобы вынести алгоритмы в отдельные классы-стратегии и передавать нужную стратегию в клиентский код.
Это паттерн используется, когда:
— Нужно использовать разные варианты одного и того же алгоритма в разных ситуациях.
— Нужно легко добавлять новые стратегии, не меняя существующий клиентский код.
— Нужно избавиться от условных операторов, выбирающих алгоритм.