Форум программистов, компьютерный форум CyberForum.ru

Собеседования по С++ для джуна - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.66
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2139 / 972 / 223
Регистрация: 30.11.2013
Сообщений: 3,241
29.07.2015, 13:22     Собеседования по С++ для джуна #1
Добрый день,

если вы бы проводили собеседования по С++ для джуна - какой вопрос по С++ вы бы припасли как самый сложный?

Кликните здесь для просмотра всего текста
Для меня пока, что самый сложный вопрос (который расскрыл бы многие области знания по С++) такой:
- опишите все факторы, которые влияют на размер экземпляра класса. Какой минимальный и максимальный размер пустого класса.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.07.2015, 13:22     Собеседования по С++ для джуна
Посмотрите здесь:

Задача с собеседования (аллокатор памяти) C++
ООП. Тестовое задание собеседования. C++
Задание с собеседования (циклы) C++
C++ Пример из собеседования по C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 13:15     Собеседования по С++ для джуна #81
Цитата Сообщение от Ilot Посмотреть сообщение
А это уже вопрос формализма. Тут никто не может быть правым или ошибаться.
Это прописано в стандарте.

Вот еще:

1.8 [intro.object]/6 Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects that are not bit-fields may have the same address if one is a subobject of the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they shall have distinct addresses. [...]

Отсюда следует, что согласно формальной терминологии С++, объекты могут иметь нулевой размер.

Добавлено через 21 час 26 минут
Кстати мы тут говорили-говорили про empty base class optimization, но так и не сказали, где эта оптимизация применяется. Попробую немного устранить этот пробел (на примере libstd++).

Давайте рассмотрим самый обычный std::unique_ptr, которым мы все так любим пользоваться. Вот его объявление:
C++
1
2
3
4
template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;
То есть класс Deleter, через который выполняется освобождение ресурса, является частью типа и присутствует в любом случае. Если мы его не указываем сами, то это будет std::default_delete<T>, который делает просто delete.
Сам объект deleter мы можем передать непосредственно в конструктор, например такой:
C++
1
unique_ptr( pointer p, Deleter d1 );
Какой отсюда пока можно сделать вывод? Вывод такой - объект, который используется для удаления ресурса, хранится в классе unique_ptr в виде скажем Deleter d. И в принципе не важно, это наш объект, который мы передали в конструктор, или умолчательный.
Смотрим дальше. Вот есть код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <memory>
 
struct Foo { int x; };
 
// пишем специализацию, потому что make_unique работает только с дефолтным делитером
// можно было написать свой класс и передавать в конструктор, указанный выше
namespace std
{
template<>
struct default_delete<Foo> {
    void operator()(Foo * ptr)
    {
        std::cout << "D is deleting a Foo\n";
        delete ptr;
    }
};
}
 
int main()
{
    auto p = std::make_unique<Foo>();
    std::cout << sizeof(p) << '\n';
    std::cout << sizeof(void*) << '\n';
}
Вывод - 8 8. Это значит, что размер указателя и unique_ptr одинаковы! Как так? Ведь мы же выяснили, что unique_ptr должен хранить внутри себя объект делитера, а это минимум 1 байт + выравнивание. Лезем в код unique_ptr и видим:
C++
1
2
typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;
 __tuple_type                                      _M_t;
То есть на самом деле unique_ptr хранит внутри себя указатель и делитер не как отдельные поля, а как std::tuple. Казалось бы, нафига? Лезем в код std::tuple и видим:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
template<std::size_t _Idx, typename _Head, bool _IsEmpty>
  struct _Head_base;
 
template<std::size_t _Idx, typename _Head>
  struct _Head_base<_Idx, _Head, true>
  : public _Head
  {
    constexpr _Head_base()
    : _Head() { }
 
    constexpr _Head_base(const _Head& __h)
    : _Head(__h) { }
 
    template<typename _UHead>
      _Head_base(_UHead&& __h)
  : _Head(std::forward<_UHead>(__h)) { }
 
    _Head&       _M_head()       { return *this; }
    const _Head& _M_head() const { return *this; }
  
    void 
    _M_swap_impl(_Head& __h)
    {
  using std::swap;
  swap(__h, _M_head());
    }
  };
 
template<std::size_t _Idx, typename _Head>
  struct _Head_base<_Idx, _Head, false>
  {
    constexpr _Head_base()
    : _M_head_impl() { }
 
    constexpr _Head_base(const _Head& __h)
    : _M_head_impl(__h) { }
 
    template<typename _UHead>
      _Head_base(_UHead&& __h)
  : _M_head_impl(std::forward<_UHead>(__h)) { }
 
    _Head&       _M_head()       { return _M_head_impl; }
    const _Head& _M_head() const { return _M_head_impl; }        
 
    void
    _M_swap_impl(_Head& __h)
    { 
  using std::swap;
  swap(__h, _M_head());
    }
 
    _Head _M_head_impl; 
  };
Мы видим специализацию шаблона! Одна - для пустого класса, тогда мы наследуемся и у нас есть empty base class optimization! И одна - если класс не пустой, тогда у нас появляется поле _Head _M_head_impl;
То есть: в данной реализации tuple у нас есть оптимизация пустых классов! Поэтому unique_ptr и использует tuple: мы автоматом получаем, что если класс делитера у нас пустой, то он не занимает у нас никакого места! Поэтому в данном случае размеры unique_ptr и обычного указателя совпадают.

Еще оптимизация пустого базового класса применяется например и в аллокаторах. Это вы можете сами посмотреть

PS фиг знает, нормально я объяснил или нет. Надеюсь поймете все
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
HighPredator
04.08.2015, 14:34
  #82

Не по теме:

Цитата Сообщение от ct0r Посмотреть сообщение
На работу, где сейчас только С++03, я не пойду, потому что придется поддерживать наверняка ужасный легаси код
Ага, только ситуация такова, что ни одна сертифицированная по ИСО организация (дев-процесс) никогда не пройдет ИСО-шный аудит на compliance при попытке использовании с++11 и старше, а так ничего... Из первых рук что называется.

hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.08.2015, 17:16     Собеседования по С++ для джуна #83
Цитата Сообщение от ct0r Посмотреть сообщение
Ну вообще имеют. Давай посмотрим на терминологию стандарта.
там лишь сказанно, что объект может содержать подобъект.
при этом, между "объектом" и "подобъектом" нигде знак равенства не ставится.

само понятие "подобъект" нужно лишь для описания взаимоотношений частей класса.

но часть класса не является классом

-------------------------------------------------------
вы можете взять размер у объекта.
но вы никак не сможете взять размер у подобъекта.

потому что любая корректная попытка будет приводить к тому,
что размер вы берете имменно у объекта.

в случае с Гайкой, получилось, что компилятор сделал выравнивание,
в результате которого, оказалось,
что под "объект-пустышку" память выделена не была,
что как бы понятно: зачем выделять память под пустоту?

но если запросить sizeof пустышки,
или запросить sizeof базового-класса-пустышки,
или кастить наследника к базе-пустышки и запрашивать...

в общем, нуля вы там никогда не получите.
потому что все подобные запросы выполняются в отношении объектов.
а не в отношении частей из которых состоит класс.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 17:25     Собеседования по С++ для джуна #84
Цитата Сообщение от hoggy Посмотреть сообщение
там лишь сказанно, что объект может содержать подобъект.
при этом, между "объектом" и "подобъектом" нигде знак равенства не ставится.
Там черным по белому написано несколько раз, что подобъект базового класса (base class subobject) это объект (object). И это не знак равенства, а отношение включения.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.08.2015, 17:28     Собеседования по С++ для джуна #85
Цитата Сообщение от ct0r Посмотреть сообщение
Отсюда следует, что согласно формальной терминологии С++, объекты могут иметь нулевой размер.
отсюда следует, что согласно формальной терминологии, подобъектымогут иметь нулевой размер.
но подобъект - не есть объект.

вы там ещё полазийте по стандарту.
где то должно быть упоминание, согласно которому,
можно делать массивы из объектов любого типа.
и поэтому, размер объекта никак не может быть нулем.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 17:31     Собеседования по С++ для джуна #86
Цитата Сообщение от hoggy Посмотреть сообщение
вы там ещё полазийте по стандарту.
где то должно быть упоминание, согласно которому,
можно делать массивы из объектов любого типа.
и поэтому, размер объекта никак не может быть нулем.
Правильно, но отчасти. Размер не может быть нулем не для object, а для most derived object. Вот такая в стандарте терминология.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.08.2015, 17:55     Собеседования по С++ для джуна #87
Цитата Сообщение от ct0r Посмотреть сообщение
Кончай троллить. Там черным по белому написано несколько раз, что подобъект базового класса (base class subobject) это объект (object). И это не знак равенства, а отношение включения.
подобъект - это именно что отношение включения.

вы можете обратиться к нему,
как к объекту, пожалуйста:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
 
 
struct base
{
    size_t getSize()const { return sizeof(*this); }
};
 
struct der: base
{
    size_t getSize()const { return sizeof(*this); }
    size_t getBaseSize()const { return base::getSize(); }
    
    int a;
    
};
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    std::cout << "size of base: " << base().getSize() <<std::endl;
    std::cout << "size of der: " << der().getSize() <<std::endl;
    
    std::cout << "size of der::base " << der().getBaseSize() <<std::endl;
    
}
Hello, world!
size of base: 1
size of der: 4
size of der::base 1
только вы при этом обращаетесь именно что к объекту, как к нормальному объекту.
а не как к части класса.
S_el
1908 / 1503 / 296
Регистрация: 15.12.2013
Сообщений: 5,921
04.08.2015, 18:01     Собеседования по С++ для джуна #88
Ferrari F1, это хорошая тема,я уже немало полезной и интересной информации узнал. Может, через пару лет, и вы из неё что-то сможете почерпнуть.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 18:22     Собеседования по С++ для джуна #89
hoggy, блин Я тебе привел стандарт. Хочешь оспаривать стандарт и продвигать в массы свою терминологию С++ - твое право, но я в этом участвовать не буду.

Добавлено через 10 минут
Еще раз докажу, что ненулевой размер относится не к object, а к most derived object, а это не одно и то же:

Unless it is a bit-field (9.6), a most derived object shall have a non-zero size and shall occupy one or more
bytes of storage.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
04.08.2015, 18:43     Собеседования по С++ для джуна #90
Цитата Сообщение от ct0r Посмотреть сообщение
hoggy, блин Я тебе привел стандарт. Хочешь оспаривать стандарт и продвигать в массы свою терминологию С++ - твое право, но я в этом участвовать не буду.
в котором достаточно ясно дается понять,
что подобъект - всегда часть объекта, и не более того.

спасибо конечно за выдержки из стандарта.
однако я продвигаю не терминологию,
а суть понятий, которые за этой терминологией скрываются.

например, я говорю вам: "объект состоит из двух подобъектов"
и вы сразу же понимаете, что я имел ввиду:
"класс состоит из двух каких то частей".

но когда вы захотите обратится к какой нибудь части,
то обращаться вы будете именно что к полноценному объекту,
а не к "части класса".

вести себя "подобъект" будет как самый обычный объект, со всеми вытекающими.
и получить его нулевого размера у вас не получится никак.


Цитата Сообщение от ct0r Посмотреть сообщение
Еще раз докажу, что ненулевой размер относится не к object, а к most derived object, а это не одно и то же:
а в чем разница то?

вот есть иерархия:
C++
1
2
struct base{};
struct der: base{ int a; };
base - это у нас что, "наиболее производный объект" что ли?

я здесь вижу:
что объект класса der состоит из инта и подобъекта класса base.
при этом объект класса base не будет иметь нулевой размер.

несмотря на то, что под подобъект base в объекте класса der,
память выделена не будет.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
04.08.2015, 21:44     Собеседования по С++ для джуна #91
Цитата Сообщение от hoggy Посмотреть сообщение
в котором достаточно ясно дается понять,
что подобъект - всегда часть объекта, и не более того.
И что подобъект - это частный случай объекта.

Цитата Сообщение от hoggy Посмотреть сообщение
спасибо конечно за выдержки из стандарта.
однако я продвигаю не терминологию,
а суть понятий, которые за этой терминологией скрываются.
Так я ж не против. Главное чтоб суть понятий не противоречит этой самой терминологии.

Цитата Сообщение от hoggy Посмотреть сообщение
но когда вы захотите обратится к какой нибудь части,
то обращаться вы будете именно что к полноценному объекту,
а не к "части класса".
Верно. Потому что подобъект - это частный случай объекта.

Цитата Сообщение от hoggy Посмотреть сообщение
вести себя "подобъект" будет как самый обычный объект, со всеми вытекающими.
и получить его нулевого размера у вас не получится никак.
Тоже верно. Но получить нулевой размер подобъекта базового класса не получится не потому, что он не нулевой и занимает память, а потому что
5.3.3 p2 The result of applying sizeof to a base class subobject is the size of the base class type.
То есть по определению sizeof возвращается размер базового класса, а не самого подобъекта базового класса. То есть ты ну вообще никак не сможешь вывести реальный размер этого самого подобъекта базового класса. А этот размер может быть в действительности меньше результата sizeof.

Цитата Сообщение от hoggy Посмотреть сообщение
base - это у нас что, "наиболее производный объект" что ли?
Им будет экземпляр класса der. Или экземпляр класса base. Но не подобъект базового класса base в объекте класса der.

Цитата Сообщение от hoggy Посмотреть сообщение
а в чем разница то?
Разница грубо говоря как раз в том, что most derived object - это object, который не subobject.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
05.08.2015, 07:35     Собеседования по С++ для джуна #92
Я смотрю пьянка до сих пор продолжается. Я конечно не хотел бы снова в ней участвовать, но все же заметил, что hoggy проводит последний (надеюсь) рубеж обороны на понятии:
Цитата Сообщение от hoggy Посмотреть сообщение
подобъекты могут иметь нулевой размер.
но подобъект - не есть объект.
Т.е. осталось убедить уважаемого hoggy, что подобъект это то же объект и для этого я хотел бы напомнить ему написааную мной фразу:
Цитата Сообщение от Ilot Посмотреть сообщение
Согласно основному принципу С++ объект существует после того как отработает его конструктор. При построении объекта производного класса отрабатывают конструкторы базового. Следовательно объект базового класса существует.
и дополню мысль: ... в составе производного.
hoggy, как вы это прокомментируете?
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
05.08.2015, 11:06     Собеседования по С++ для джуна #93
Цитата Сообщение от ct0r Посмотреть сообщение
Тоже верно. Но получить нулевой размер подобъекта базового класса не получится не потому, что он не нулевой и занимает память, а потому что
5.3.3 p2 The result of applying sizeof to a base class subobject is the size of the base class type.
То есть по определению sizeof возвращается размер базового класса, а не самого подобъекта базового класса. То есть ты ну вообще никак не сможешь вывести реальный размер этого самого подобъекта базового класса. А этот размер может быть в действительности меньше результата sizeof.
примерно об этом я и толдычу уже хз сколько времени.

я несколько раз делал ударение на различие понятий "объект" и "подобъект".
и делал акцент: работать мы можем только с объектами.

а "подобъект" - всего лишь абстракция,
которая обозначает отношение включения.

я считаю некорректно называть "подобъект" частным случаем "объекта".

вот есть объект "автомобиль".
мы поставили его на "паром".

от этого этот "автомобиль" не стал быть "частным случаем автомобиля".
это тот же самый автомобиль.
и мы можем к нему обратиться,
и в этом случае обращение будет именно как к "объекту-атомобилю",
а не как к "части парома".

что касается парома - по некоторым правилам все его подобъекты будут расставлены.
для автомобилей-пустышок за ненадобностью не будет выделено места.
хотя фигурировать они по прежнему будут, и к ним можно будет обращаться.
вот и все.

Цитата Сообщение от Ilot Посмотреть сообщение
hoggy, как вы это прокомментируете?
Цитата Сообщение от Ilot Посмотреть сообщение
Согласно основному принципу С++ объект существует после того как отработает его конструктор. При построении объекта производного класса отрабатывают конструкторы базового. Следовательно объект базового класса существует.
это - очень правильная мысль.
в которой весьма точно подмеченно - конструкторы отрабатывают для объектов.
вы можете попробовать взять размер объекта в конструкторе,
и убедиться, что он - не нулевой.

объект базового класса действительно существует.
к нему можно обратиться.

цемес в том, что это будет обращение именно к объекту,
а не к "подобъекту".

ваша точка зрения:
вы считаете, что подобъект - это объект,
который был включен в состав другого объекта.
и в отдельных ситуациях такой подобъект,
может не занимать памяти.
следовательно иногда объекты могут быть нулевого размера.

вроде бы все логично и верно.

но понимаете, все дело в том,
что формально никаких подобъектов не существует.

это - абстракция, которая фимгурирует лишь в декларации классов,
и в голове программиста.

вся работа ведется только с объектами.
а объекты нулевыми быть не могут.
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,284
05.08.2015, 12:08     Собеседования по С++ для джуна #94
Вы бы лучше код с таким усердием писали
ture
 Аватар для ture
417 / 310 / 120
Регистрация: 27.11.2014
Сообщений: 1,004
05.08.2015, 12:16     Собеседования по С++ для джуна #95
Кто или что такое Джуна?
(вики я уже смотрел)
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
05.08.2015, 12:21     Собеседования по С++ для джуна #96
Цитата Сообщение от hoggy Посмотреть сообщение
я считаю некорректно называть "подобъект" частным случаем "объекта".
Пиши тогда в комитет, если они тебя выслушают и согласятся, поправят стандарт, - то окей. Но на данный момент подобъект - частный случай объекта.

Цитата Сообщение от hoggy Посмотреть сообщение
ваша точка зрения:
вы считаете, что подобъект - это объект,
который был включен в состав другого объекта.
и в отдельных ситуациях такой подобъект,
может не занимать памяти.
следовательно иногда объекты могут быть нулевого размера.
Так и есть.

Цитата Сообщение от hoggy Посмотреть сообщение
но понимаете, все дело в том,
что формально никаких подобъектов не существует.
Что для тебя значит формально? Для меня существование термина subobject в стандарте вполне подходит под формально. Мы разговариваем сейчас в терминах С++. А тут даже обычная переменная типа int - объект.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
05.08.2015, 12:22     Собеседования по С++ для джуна #97
ture, Собеседования по С++ для джуна
Кроме вики нужно еще смотреть и тему.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
05.08.2015, 12:35     Собеседования по С++ для джуна #98
Цитата Сообщение от ct0r Посмотреть сообщение
Что для тебя значит формально? Для меня существование термина subobject в стандарте вполне подходит под формально. Мы разговариваем сейчас в терминах С++. А тут даже обычная переменная типа int - объект.
термин существует, и описывает отношение: объект1 является частью объекта2.
а вот "частей объекта" не существует. существуют только объекты.
это все.
ct0r
C++/Haskell
 Аватар для ct0r
1549 / 568 / 39
Регистрация: 19.08.2012
Сообщений: 1,174
Завершенные тесты: 1
05.08.2015, 12:53     Собеседования по С++ для джуна #99
hoggy, короче забей. Мы слишком много времени тратим на выяснение фактов, которые в принципе никак не помогут писать нам лучший код.
ture
 Аватар для ture
417 / 310 / 120
Регистрация: 27.11.2014
Сообщений: 1,004
05.08.2015, 12:59     Собеседования по С++ для джуна #100
Сеньёр выбирает себе мальчика по вкусу. Потому что есть задел работ, который намеревается передать мальцу. По сути мальчик может не знать даже с++, если сеньёр захочет. Рекомендую взять студента, т.к. они быстро обучаются самостоятельно, притаскивают из ВУЗа перлы преподов, которые будут полезны даже сеньеру.

И да - мальца придется подучить программировать, а значит нужен сговорчивый и без "так не делают, потому что на прошлой работе так не делали".
Yandex
Объявления
05.08.2015, 12:59     Собеседования по С++ для джуна
Ответ Создать тему
Опции темы

Текущее время: 13:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru