Как стать автором
Обновить

"Лаборатория Касперского": как попасть и чем заняться? Взгляд изнутри

Время на прочтение 18 мин
Количество просмотров 55K
Может показаться, что в крупную ИБ-компанию очень сложно попасть: нужно пройти семь кругов ада, найти подвох в любой задаче, знать биографию всех руководителей и всю подноготную самой компании. Так ли это? Глава управления базовых технологий «Лаборатории Касперского» Игорь Маслов сам когда-то проходил этот путь: семь лет назад он пришел на очное собеседование, а сейчас руководит одним из ключевых отделов и решает нетривиальные задачи. Мы поговорили с ним — о том, кого и за что берут в «Лабораторию Касперского», спокойно ли живется разработчикам, какие скиллы способствуют карьерному росту и как в ближайшее время изменится процесс разработки. Для стойких и уверенных в себе бонус: тестовое задание — пропуск на финальное собеседование в компанию.

— Какую роль в разработке защитных решений в «Лаборатории Касперского» ты играешь?
— Я руковожу управлением базовых технологий численностью в 150 человек. Это отдел, который занимается созданием «кирпичиков» для антивирусов. «Кирпичики» используются во всех наших продуктах: десктопных, корпоративных, серверных. Это в основном С++ код, осуществляющий бизнес-логику. Он отвечает за обновление баз, отправку различной статистики в наши облака, перехват системных событий, агрегацию событий, которые перехватили, от наших драйверов и передачу их в движки, за реакцию на эти события: блокировку, подмену трафика (когда хотим показать страничку и сказать, что данные конкретной странички — фишинг).
— А как ты оказался в «Лаборатории Касперского»?
— В «Лабораторию Касперского» я пришел около 7 лет назад. Меня позвали просто как С++ разработчика, без особой конкретики. Вообще по вакансиям, особенно для программистов, зачастую сложно понять, чем в итоге придется заниматься. В неприметном месте можно найти интересный стартап или, наоборот, кажется, что компания хорошая — а по факту приходится писать банальные скрипты.
Так вот, я пришел, прошел несколько технических собеседований. Вообще первое должно было быть в Anti-Malware Research — это исследовательское подразделение, которое занимается антивирусной защитой, разрабатывает технологии. Но я не фанат research-подразделений — мне нравится создавать продукты, быть ближе к разработке, чтобы пользователи могли быстрее увидеть фичи. Да и сами фичи более явные. В research-подразделении улучшение какого-нибудь детекта не так заметно.
Я спросил прямо у входа: «Это у вас какое подразделение?». Мне говорят: «Anti-Malware Research». Я говорю: «Ресерчем надо заниматься?» «— Ну да». «— Ой, а я не хочу в ресерч-подразделение». Это было первое собеседование.
В итоге меня позвали в продуктовый департамент, где и сделали оффер.
— Как проходили собеседования? Какие вопросы задавали?
— Я помню основной смысл. Проверяли знание языка, в основном С++, понимание exception safety, конструкций языка, классов, виртуализации. Еще мне предложили разработать не очень сложный алгоритм. И, соответственно, WinAPI. Вообще на собеседованиях в «Лаборатории Касперского» спрашивают по той платформе, с которой будет работать человек. Устройство памяти, процессов, потоков.
— А ты сам проводишь собеседования?
— Я присутствую на технических собеседованиях в своей продуктовой команде. До недавнего времени я программировал, скиллы вроде не потерял, для собеседования их хватает.
— У тебя есть свое фирменное задание для новичков?
— Сейчас мы делаем больший упор на алгоритмы и архитектуру ОС и меньший — на язык программирования. Я люблю спрашивать про память: что такое виртуальная память, как она устроена, как в современных процессорах мапятся физический и виртуальный адреса. И про всякие подводные камни, особенности работы.
— В твоем отделе есть свои методики подбора сотрудников?
— Базовый принцип: собеседование проводят потенциальные коллеги кандидата. Обычно это старшие разработчики, тимлиды. Мы считаем, что в процессе разговора можно не только выявить технические скиллы, но и понять, приятно ли общаться с человеком, будет ли комфортно работать с ним. Ведь разработка — это не просто хардкорный кодинг, но и общение. Поэтому и люди нам нужны компанейские.
С интересным кандидатом я могу дополнительно пообщаться лично — по телефону или даже в телеграме. Мы вообще всегда оставляем кандидату контакты, чтобы можно было уточнить непонятные вопросы после собеседования. Вот, например, недавно я взял человека, с которым общался по телефону два или три раза по полчаса. Он остался доволен и пришел к нам, сейчас трудится над платформой.
— А на что еще обращаете внимание?
— Главное, чтобы мы нашли общий язык. Еще очень важна самостоятельность — чтобы сотруднику не требовался постоянный саппорт. Этим как раз старший разработчик и отличается от младшего: первый может самостоятельно решать сложные задачи, а второму требуется помощь.
Но, к сожалению, самостоятельность практически нереально проверить на собеседовании. Да, можно понять скилл решения проблем — например, с помощью непростой алгоритмической задачи. Но самостоятельный человек или нет, можно узнать только в процессе работы. И зачастую бывает так, что хорошие технические специалисты, которые много знают, не обладают этим навыком.
Школа. Разработка. Управление
— Как ты стал программистом?
— Я с детства увлекался математикой, как и многие другие разработчики. Попал в физматшколу МГУ и уже тогда планировал, что пойду в разработку. После школы поступил на профильный факультет — ВМК МГУ. Там я уже более серьезно занялся программированием и на третьем курсе начал работать. На четвертом — вышел на фултайм. Мне нравится разработка, другого для себя вообще не рассматривал.
— Сложно было одновременно учиться и работать?
— Вообще да. Месяцами на четвертом и пятом курсах я работал без выходных, ездил на учебу в рабочие дни. Зато это помогло стать тимлидом команды уже через год после окончания университета. В «Лабораторию Касперского» я пришел на должность senior-разработчика, потом стал тимлидом и менеджером.
— Зачастую разработчики — интроверты и им сложно перестроиться с индивидуальной работы на управление людьми. Как прошел переход у тебя?
— Я не интроверт, наоборот, рад общению, и работать менеджером мне довольно легко. Мне нравится быть тимлидом: можно сделать куда больше, задачи — сложнее и амбициознее, это доставляет огромное удовольствие.
— Если говорить о менеджерских функциях, ты следишь за работой подчиненных? Как разбираешься с потоком задач на отдел? Проверяешь качество выполнения?
— У меня есть несколько команд, где руководят менеджеры и одна небольшая, где я — непосредственно проджект-менеджер. С менеджерами, которые у меня в подчинении, мы работаем «по целям»: оговариваем критерии, по ним строим план работы и проверяем ее выполнение. У моей же продуктовой команды есть обычный план работы и бэклог с важными задачами и приоритетами. Мы работаем двухнедельными итерациями. Берем задачу, стараемся выполнить. Раз в неделю — планерки. Наша команда самостоятельная, и многие проблемы нам удается решить без привлечения руководства.
— Часто ли приходится задерживаться допоздна?
— Бывают ситуации, когда нужно выйти и закрыть проект. Но это происходит редко — когда выходит релиз фронтов с большим количеством изменений и доработок.
— А раньше, когда только начинал работать в «Лаборатории Касперского», все было так же спокойно?
— Когда я только начинал, релизы фронтов были более сложным мероприятием, чем сейчас. Мы активно развиваем автоматизацию процессов и тестирования и сейчас все проходит заметно быстрее. Жизнь разработчика упростилась, я бы так сказал.
У меня была ситуация, тогда я еще был на испытательном сроке, когда до релиза очередного фронтенда Kaspersky Internet Security оставалась неделя. Мне дали баг, говорят: «Игорь, поправь». Я баг поправил, закоммитил его в системе контроля версий, прошел ревью и поехал домой. Приехал, понял, что баг не исправлен полностью. У меня большой стресс — гиперответственность и все такое. На следующий день, в субботу, в семь утра помчался в офис и успел все исправить. А так как без ревью нельзя коммитить — написал тимлиду: «Если вы на выходных придете, то, пожалуйста, посмотрите, я исправился».
— Когда был первый серьезный успех?
— Как раз в следующий релиз фронта. К тому моменту мы переделали бизнес-логику анализа сетевого траффика: полностью переписали ее. Работа заняла чуть меньше года, и мы очень неплохо справились: избавились от огромного пласта legacy-кода и перевели продукт на новые рельсы. Это был реальный челлендж.
Дело в «плюсах»
— Расскажи, как проходит рабочий день команды. Что занимается программист, какие задачи он решает?
— Обычно разработчики начинают день с просмотра писем, вопросов, которые накопились с вечера или раннего утра. Все задачи в продуктовых командах идут через систему тикетов, сотрудник выбирает себе нужные и занимается ими.
Главный инструмент — С++, основной код и движки у нас на нем. Решение задачи состоит из обычных этапов: написания кода, локальное тестирование и отладка, код ревью, автотестирование в системе CI и деливери доработок в продукты.
— Чем еще пользуетесь?
— Основные рабочие инструменты кроме С и С++ это: стек .NET для автоматизации внутренних процессов, Python для различных частей нашей CI системы и JS для плагинов браузеров и других вещей, где без него не обойтись.
— Занимается ли твой отдел мобильной разработкой?
— Есть ряд приложений, для которых мы поставляем базовые компоненты. Они написаны на С++. Дальше компоненты используются уже в нативном формате, портировать их можно без проблем. Вообще большинство high performance приложений или игр, в AppStore или в Google Play, написаны на С++, — если и не полностью, то большая часть приложения точно. Скорее всего, те же Angry Birds или Cut the Rope. Продукты С++ работают быстрее, чем на Java или Swift — так как это высокоуровневые языки с «дорогими» абстракциями и виртуальной машиной.
— То есть в основном вам нужны знающие «плюсы»?
— Да, основная разработка на С++, 99%, и 1% — JS. Есть и инфраструктурные команды на Python и .NET.
— А если человек хорошо знает, например, Java? Можно ли его переучить или проще взять спеца именно по C++?
— Я считаю, что хорошего разработчика можно и переучить. По идее человек должен не просто знать язык программирования, а уметь работать с абстракциями — тогда и переучиться будет несложно. У нас была такая ситуация с .NET стеком.
— Что ждет ваш отдел в ближайшем будущем? Будут ли какие-либо кардинальные изменения?
— У нас в команде есть разработчики кода и разработчики автотестов. И мне очень хочется объединить эти роли в одну. Одни разработчики пишут много маленьких тестов (Unit-тестов), а другие спецы пишут крупные интеграционные. Возникает определенное недопонимание: периодически одни профессионалы не очень понимают специфику огромных интеграционных тестов, а другие не очень хорошо знают код, который тестируют. Отсюда случаются ситуации, когда ругались то на код, то на тесты.
Мне это не очень нравится: роли хочется сблизить, чтобы сотрудники могли одновременно писать код и работать над тестами любого уровня. Плюс, выделить отдельную роль чисто по инфраструктуре, фреймворкам. Глобально вот такая идея развития.
— Планируете ли брать новых сотрудников? Если да — то под какие задачи?
— У нас есть несколько свободных позиций, связанных с разработкой компонентов сетевого анализа. К слову, я там начинал. Не хватает людей и в команде, которая работает над драйверными компонентами системного перехвата. В целом задач много, они сложные, но интересные!
— Например?
Новые задачи у нас есть в нескольких блоках:
  • Мы постоянно пытаемся совершенствовать наши решения. Например, мы переделываем систему распространения наших драйверов в продуктах. В установках драйверов куча подводных камней: обновления, откаты операционных систем. На это накладываются наши патчи. В результате получается не очень детерменированный стейт, который мы хотим сделать более предсказуемым. По пути решив проблему с выпуском патчей для новых версий ОС.
  • Мы делаем очень большой упор на новые продукты. Мы понимаем, что антивирус не вечен, нельзя бесконечно «пилить» его и быть успешными. Тут — решение задач в различных новых для нас направлениях и продуктах, таких как Anti Targeted Attack Platform, развитие новых десктоп-приложений.
  • У нас довольно много инфраструктурных задач по сборке и автотестированию большого объема кода. Мы хотим, чтобы каждый коммит в наш код проверялся (собирался и запускал тесты) на всех продуктах за пару десятков минут.
  • Ну и всегда актуальная задача — делать код высокопроизводительным. Например, мы очень хотим сделать антибаннер не только большим с точки зрения покрытия, но и еще менее тормозным, как классические расширения.
— Как часто выходят новые продукты?
— Мажорные версии продуктов с кучей фич — например, тот же Kaspersky Internet Security, выходят, в среднем, раз в год. Но у нас много патчей, и зачастую работа над ними — чуть ли не как отдельная разработка. Вот, например, смотрите, сейчас Microsoft раз в полгода выпускает апдейт для Windows. По факту он как новая операционка — слишком много изменений в ядре. Для нас каждый такой апдейт равносилен выходу новой ОС с полноценной разработкой продукта под нее. Для меня это как челлендж: раз в полгода выкатить поддержку для новой «винды». Но каждый раз нашей команде это удается!
— А что нужно, чтобы продукты выпускались быстрее, а вам было проще успевать за апдейтами?
— В первую очередь, чтобы правильные и нужные вещи делались легко, а не правильные и не хорошие — долго и мучительно (тогда их не будут делать). Например, мы сейчас уходим от компонентной разработки.
Здесь подход такой: отдельно разрабатываются стабильные интерфейсы и реализовываются компоненты с данными интерфейсами, затем связываются и вроде бы все замечательно. До того момента, пока интерфейсы не начнут меняться. Условно говоря, есть первая версия компонента, которую используют все. Затем появляется вторая версия, с доработкой или изменением API. Одни продукты на него переходят, а другие — нет. А потом всем вдруг нужно перейти на новый компонент. В такой ситуации сложно подсчитать ресурсоемкость переезда, плюс нужно будет чистить баги — это очень большой и дорогой интеграционный момент.
Поэтому мы хотим изменить подход и перейти в так называемый монорепозиторий с зелеными тестами. Его суть проста: когда изменяется интерфейс, его нужно сразу проинтегрировать во все продукты. При этом мы поддерживаем тотальную валидацию: каждый коммит должен переводить систему из зеленого состояния тестов в зеленое состояние, иначе коммит уберется.
Другими словами, раньше, до отхода от компонентной разработки, интерфейс можно было исправлять только в рамках одного проекта. Сейчас мы можем вносить изменения одновременно по всем проектам. В итоге продукт быстрее доходит до стадии релиза. И сам процесс становится более предсказуемым.
Однако у системы с монорепозиторием с зелеными тестами есть определенный нюанс — она дорогая в инфраструктурном плане. Наши продукты — это гигабайты кода. Код нужно быстро собирать, валидировать и тестировать — а это не так просто. В принципе на рынке есть готовые продукты, но нельзя купить одну стороннюю систему CI, которая позволит все сделать быстро — под наши задачи одного продукта недостаточно. Поэтому мы разрабатываем свою CI-систему. Ведь быстрая разработка заключается не в том, что ты быстро печатаешь, а в том, что ты можешь быстро править и доставлять изменения клиентам.
— Получается, вы планируете полностью изменить систему тестирования своих продуктов?
— Скорее, систему доставки в прод. Мы не будем выстраивать многоступенчатую сборку, а автоматизируем ее.
— А что еще может дать отход от компонентной разработки?
— Разработчик, работающий с общим кодом, понимает, где и какой компонент используется, и может внести изменения. Еще момент: в общем коде можно применять best practice соседа, наработки коллег. Хороший reuse, когда используется не копипаст кода, а уже готовые шаблоны. В каждой команде есть свой набор утилит, хелперов, теперь их можно будет использовать сообща. Если разрабатывается фреймворк или контейнер, нельзя просто переименовать какой-то метод. Его нужно править вручную во всех клиентах, это головная боль. Теперь ее не будет.
В принципе это основное, что касается разработчиков. Для менеджеров новая система детерминирует риски использования нового кода, которые будут всегда актуальными.
Как попасть в «Лабораторию Касперского» и чем заняться
— На собеседовании вы сразу, через тестовые задачи, погружаете человека в то, чем ему придется заниматься?
— Нет, такого нет, у нас абстрактные задачи, не привязанные к нашей проблемной области. На базовое понимание.
— А как тогда понять, что человек действительно готов и может работать в нужной вам сфере?
— У нас обычный испытательный срок в три месяца, за это время мы все понимаем, да и он тоже.
— У вас есть помощь новичкам? Не бросаете?
— Case-by-case. «Синьоры» более самостоятельны, им опека не нужна — наоборот, будет мешать. А junior-ам, конечно, помогаем — для каждого назначаем ментора, который сможет объяснить и подсказать по задачам. Но вообще все зависит от человека: мы стараемся создать максимально комфортные условия для каждого. И людям у нас нравится: обычно они остаются у нас на много лет.
К тому же, у нас есть программа адаптации для новичков, которая состоит из нескольких этапов. Каждые две недели здесь проходят трехчасовые вводные встречи для таких сотрудников. Их знакомят с историей компании, продуктовой линейкой и руководством, рассказывают о том, как устроена наша жизнь. Например, как оформить отпуск, уйти на больничный, что делать, если возникла проблема с компьютером, какие есть правила безопасности в офисе и так далее. Важные и полезные вещи.
— Работать приходится в офисе? Или можно удаленно?
— У нас гибкий рабочий график, можно поработать из дома, если приболел или что-то случилось, — для этого есть удаленный доступ. Но постоянно работать удаленно нельзя, нужно общаться с клиентами и тимлидом.
— С продакт-менеджерами, бизнес-отделом есть взаимодействие?
— Очень и очень плотное. Продакт-менеджеры сидят рядом с разработчиками, в соседнем опенспейсе-кубике (у нас пространство в офисе с помощью оформления поделено на небольшие «кубики», где обычно сидят по 4-6 человек). Для нас важно постоянно взаимодействовать друг с другом, мы очень близко, в одной команде, все общаемся между собой.
— Какие интересные задачи приходилось решать?
— За время работы в компании я занимался несколькими направлениями. Но все они так или иначе связаны с перехватом трафика и его анализом. Я уже говорил про переписывание бизнес-логики перехвата в наших дестоп-продуктах. После этого много времени я посвятил улучшению технологии безопасных платежей. Это функциональность по защите онлайн-операций пользователя. Изначально функциональность выглядит просто — при переходе на сайт банка или совершении иных финансовых онлайн операций нужно включить функционал и предотвратить любое вмешательство. Но проблемы случаются, как всегда, во время реализации. Нам оказалось сильно проще и эффективнее запустить новый браузер вместо защиты уже работающего и проконтролировать, чтобы в него никто не попал. С таким решением существует много минусов, но основной — это перенос контекста работы из обычного браузера в нашу защищенную копию. Например, пользователь заходит в личный кабинет провайдера и хочет оплатить интернет. Мы понимаем, что сейчас будут вводить данные в платежной системе и переносим сеанс в защищенную копию, но теряем факт логина в личный кабинет. Еще одна сложная задача — это определение самого факта начала финансовой операции. Просто по адресу это понять нельзя, так как много всяких картинок и остального CSS выкачивается браузерами. Поэтому нужно анализировать контекст.
— А свобода творчества у сотрудников есть? Могут запилить свой продукт в рамках продуктов «Лаборатории Касперского»?
— Выделить рабочий день на сторонние проекты, как в Google, не получится — мы живем в рамках бизнеса. Но в рамках компании, работающей в сфере кибербезопасности, можно что-то придумать и получить поддержку. Ведь часто возникает мысль: «О, мы можем защитить вот это». И приходит разработчик с proof-of-concept, предлагает сделать новую защищенную технологию, новый продукт. И мы делаем.
У нас есть защита видео, опять же, safe-браузер начинался как обычный контейнер. Это все шло от концептов разработчика, а бизнес это принял и дал зеленый свет для реализации.
Приложение для мобильных устройств «Who Calls» тоже продвигали как идею одного из менеджеров. Звонки с неизвестных номеров и спам были его личной проблемой, и ее решение он воплотил в продукте. И сейчас активно его развивает, получает от нас фидбэк.
У нас есть защита UEFI: разработчик купил новый компьютер, а там программируемый BIOS. Сотрудник разработал proof-of-concept и предложил написать антивирус, который будет проверять загрузочную область. Идея понравилась, под нее выделили разработчиков. Недавно продукт выпустили, он продолжает развиваться и живет своей жизнью.
— А соискатель может прийти к вам с какой-то идеей?
— У нас есть бизнес-инкубатор, к примеру, там делают систему электронного голосования на основе блокчейна. Идеи отправляются в инкубатор с конференций или других внешних коммуникаций. Туда, например, пришла идея с внутреннего хакатона.
О тестовых заданиях
— Какие вообще могут быть тестовые задания?
— В основном про язык и про систему. Почему такой код не компилируется, что нужно сделать, чтобы компилировался. Почему он работает неверно? Это все задачи на С++ и знание операционных систем.
Задания не особо изменились после того, как я пришел семь лет назад: мы проверяем знание системы, основных моментов языка, на котором пишет человек: классы, виртуализация, наследование исключение, базовые контейнеры, библиотеки. Совсем замечательно, если знает шаблоны. И даем какие-то несложные задачи на алгоритмы. Написать базовый алгоритм, std::remove, к примеру, или какую-нибудь сортировку. Тут важно понять, как человек пишет код.
— Можешь дать какие-то советы соискателям? Что нужно делать, прежде чем отсылать резюме?
— Повторить С++ и быть готовым написать какой-то код на листочке, причем аккуратно. Желательно, чтобы это еще и работало. Это быстро тренируемый скилл, тем более, много платформ для олимпиадного программирования, можно взять и прямо в браузере писать на С++. Без автоподстановок и хелперов.
Но в целом мы больше спрашиваем по теории, та же структура данных: деревья, хэш-таблицы, какие контейнеры когда применять. А вот других интерактивов нет.
— А как оцениваете?
— У нас субъективная оценка, каждый интервьюер выставляет персональные баллы. Результат тестового задания — написанный алгоритм, в котором можно посмотреть, указать, где ошибки. И на основе отзывов принимаем решение — брать или не брать.
— Высылаете результаты тестового задания?
— Это не требуется — мы в большинстве случаев сразу говорим кандидату результат. Тестовые задания — часть собеседования, нам важно понимать, как человек общается, взаимодействует и думает. Если мы берем senior-а, часто даем менее структурированную задачу: чтобы программист продемонстрировал свои навыки и экспертность. Конечно, он может задавать уточняющие вопросы. Младшим же, если есть проблемы, сразу говорим, что и как, предлагаем почитать литературу.
— А в течение какого срока можно снова откликаться на вакансии?
— У нас нет строгой системы, и мы смотрим человека сразу на все вакансии. Если мы не берем его к себе, но у него хорошие скиллы — отправим в подходящую команду. К примеру, если соискатель хорошо знает машинное обучение, которое нужно в исследовательском отделе, переправим резюме туда.
Другой вариант, если уровень кандидата колеблется между сеньором и джуниором. Тогда его могут позвать в отдел, где нужен джуниор.
— Если комплексно, как проходит собеседование? Везде тестовые задания?
— Нет, достаточно зареплаиться — а мы уже решаем, звать ли кандидата на очное собеседование. А по результатам очного уже определяем — посылать оффер, отказать или позвать на повторное техническое собеседование. Да, как раз сейчас в свой отдел я ищу разработчика C++/Python, Dev tools.

Тестовое задание
Команда «Лаборатории Касперского» подготовила несколько задач по C++, решив которые, вы не только получите приглашение на финальное собеседование в «Лабораторию Касперского», но и сможете выиграть ценный приз — «Рюкзак добра». Только победители узнают, что внутри. Присылайте решения через форму обратной связи ниже, а команда экспертов (с Игорем Масловым в составе) выберет самые крутые варианты и пригласит их авторов на финальное собеседование. Бонус - экскурсия по офису и дополнительные призы от компании.
Вопрос 1
Почему программа не собирается? Как можно поправить сборку?
#include <string>
#include <memory>
#include <iostream>
#include <iomanip>
class Item
{
public:
	virtual ~Item() { }
	Item(const char* data): m_data(std::make_unique<std::string>(data)) {  }
	
	virtual const std::string GetContent() const { return m_data ? *m_data : ""; }
private:
	std::unique_ptr<std::string> m_data;
};
class ItemEx : public Item
{
public:
	ItemEx(const char* data, const char* dataEx): Item(data), m_dataEx(std::make_unique<std::string>(dataEx)) {  }
	
	virtual const std::string GetContent() const override { return Item::GetContent() + (m_dataEx ? *m_dataEx : ""); }
private:
	std::unique_ptr<std::string> m_dataEx;
};
void Func()
{
	ItemEx item("123", "456");
	std::cout << item.GetContent() << std::endl;
	ItemEx newItem = std::move(item);
	std::cout << newItem.GetContent() << std::endl;
	std::cout << item.GetContent() << std::endl;
}
int main()
{
	Func();
}
Вопрос 2
Какие проблемы есть в программе ниже?
#include <vector>
#include <string>
#include <iostream>
#include <iomanip>
template<typename ContainerType>
ContainerType BuildFromString(const std::string& s)
{
	ContainerType data;
	for (char c: s)
	{
	      data.push_back(static_cast<typename ContainerType::value_type>(c));
	}
	return data;
}
void UsingAuto()
{
	const std::string s = "1234";
	auto v32 = BuildFromString<std::vector<uint32_t>>(s)[0];
	auto v16 = BuildFromString<std::vector<uint16_t>>(s)[1];
	auto vbb = BuildFromString<std::vector<bool>>(s)[2];
	std::cout << v32 << " " << v16 << " " << vbb << std::endl;
}
int main()
{
	UsingAuto();
}
Вопрос 3
Есть ли проблемы в программе?
#include <iostream>
#include <iomanip>
class VerySimpleItem
{
public:
	bool IsNull() const
	{
	      if (this == nullptr)
		      return true;
	      return false;
	}
};
void Func()
{
	VerySimpleItem* item1 = nullptr;
	VerySimpleItem item2;
	std::cout << "Is 1-st null: " << item1->IsNull() << std::endl;
	std::cout << "Is 2-nd null: " << (&item2)->IsNull() << std::endl;
}
int main()
{
	Func();
}
Вопрос 4
Почему программа не собирается? Как можно поправить сборку?
////////////////////////////////////////
// class.h
#include <memory>
class Impl;
class Class
{
public:
	Class();
	void DoSomething();
private:
	std::unique_ptr<Impl> m_impl;
};
// end of class.h
////////////////////////////////////////
////////////////////////////////////////
// class.cpp
#include "class.h"
#include <iostream>
#include <iomanip>
class Impl
{
public:
	void DoSomething() { std::cout << "Done" << std::endl; }
};
Class::Class()
	: m_impl(std::make_unique<Impl>())
{
}
void Class::DoSomething()
{
	m_impl->DoSomething();
}
// end of class.cpp
////////////////////////////////////////
////////////////////////////////////////
// main.cpp
#include "class.h"
int main()
{
	Class item;
	item.DoSomething();
}
// end of main.cpp
////////////////////////////////////////
Вопрос 5
Что примерно будет выдано в output и почему? Как можно оптимизировать программу?
#include <iostream>
#include <iomanip>
#include <vector>
class Element
{
public:
	Element(const uint64_t v)
	{
		m_p = new uint64_t();
		*m_p = v;
	}
	Element(const Element& rhs)
	{
		m_p = new uint64_t();
		*m_p = *rhs.m_p;
		std::cout << "copy ctor: " << *m_p << std::endl;
	}
	Element(Element&& rhs)
	{
		m_p = rhs.m_p;
		rhs.m_p = nullptr;
		std::cout << "move ctor: " << *m_p << std::endl;
	}
	Element& operator=(const Element& rhs) = delete;
	Element& operator=(Element&& rhs) = delete;
	~Element()
	{
		if (m_p)
			delete m_p;
	}
private:
	uint64_t* m_p;
};
void Func()
{
	std::vector<Element> elements;
	uint64_t id = 1;
	elements.emplace_back(id++);
	while (elements.capacity() > elements.size())
	{
		elements.emplace_back(id++);
	}
	elements.emplace_back(id++);
}
int main()
{
	Func();
	return 0;
}
Вопрос 6
Как поправить сборку программы?
#include <tuple>
#include <cassert>
#include <utility>
struct SomeClass
{
	SomeClass (int a, int b)
	{ 
		assert (a == 7);
		assert (b == 42);
	}
};
template <class Base>
struct Proxy : Base
{
	template <class... T1>
	Proxy (std::tuple<T1...>&& params)
			:/*Необходимо достать данные из tuple и передать параметры по одному в конструктор базы*/
	{
	}
};
int main ()
{
	Proxy<SomeClass> (std::forward_as_tuple (7, 42));
	return 0 ;
}
Вопрос 1
Вопрос 2
Вопрос 3
Вопрос 4
Вопрос 5
Вопрос 6
Ваш email
Теги:
Хабы:
+11
Комментарии 44
Комментарии Комментарии 44