С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.66
rikimaru2013
C++ Game Dev
2440 / 1133 / 240
Регистрация: 30.11.2013
Сообщений: 3,690
#1

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

29.07.2015, 13:22. Просмотров 4254. Ответов 100
Метки нет (Все метки)

Добрый день,

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

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

Трудоустройство: что нужно знать для успешного прохождения собеседования в самые крутые компании? - C++
Добрый вечер. Напишите пожалуйста список того, что нужно знать для успешного прохождения собеседования в самые крутые компании, c++...

Пример из собеседования по C++ - C++
Граждане, есть такой пример: class B { private: virtual void f() { std::cout << "B::f()" << std::endl;} public: void g() {...

Задания с++ с собеседования - C++
Предложите ваши варианты решения заданий 1. Перечислите все проблемы, которые вы видите в данном коде: class Foo { public: ...

Задание с собеседования (циклы) - C++
День добрый! Был сегодня на собеседовании, и было такое задание где было такое задание: Описать одним предложением что делает данная...

Задача с собеседования (аллокатор памяти) - C++
Вопрос звучит так: "Напишите быстрый аллокатор памяти" Как я его понимаю: можно пожертвовать растратой памяти, всякими наворотами,...

ООП. Тестовое задание собеседования. - C++
Это тестовое задание для устройста на работу. Я не совсем понимаю что от меня хотят. Не могли бы вы мне далее составить набросок плана...

100
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.08.2015, 12:55 #76
hoggy, думаю я понял ход вашей мысли.
Размер отдельного объекта не может быть нуль. Так? С этим я согласен.
Но рассмотрим такой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
struct A {};
struct B : A {
    int x;
};
void func(const A& a) {
    std::endl(std::cout);
    std::cout << "sizeof(a) is " << sizeof(a);
    std::endl(std::cout);
    std::cout << "adress a is " << &a;
}
int main(){
    B b;
    std::cout << "sizeof(b) is " << sizeof(b);
    std::endl(std::cout);
    std::cout << "sizeof(b.x) is " << sizeof(b.x);
    func(b);
    std::endl(std::cout);
    std::cout << "adress b is " << &b;
    std::endl(std::cout);
    std::cout << "adress b.x is " << &b.x;
    return 0;
}
Передача в функцию происходит по ссылке, т.е. мы передаем существующий объект без создания временного.
Как легко видеть адреса не изменились, однако sizeof(a) вернул 1. Вопрос: если как вы говорите объект не может иметь нулевой размер то откуда в структуре взялся лишний байт?
Цитата Сообщение от hoggy Посмотреть сообщение
"часть базового класса" - не является ни объектом, ни структурой.
это не более, чем абстракция в вашей голове.
А как же приведенный пример? С чем же мы тогда работаем в теле функции если повторюсь передача происходит по ссылке?
Действительно производный класс слагается не только из базовых. В нем может быть кое-что еще начиная от выравнивания завершая таблицей виртуальных функций. Однако в производном классе обязательно присутствует бинарно совместимая часть соответствующая базовому классу. И работать с этой частью структуры можно как с объектом базового класса включая обращение к полям класса и вызовом функций членов. А если так, то почему вы утверждаете, что в наследнике нет объекта базового класса. Чем докажите?

Добавлено через 17 минут
Более того. Согласно основному принципу С++ объект существует после того как отработает его конструктор. При построении объекта производного класса отрабатывают конструкторы базового. Следовательно объект базового класса существует.
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
03.08.2015, 14:31 #77
Ilot, hoggy, я не понимаю, вы по поводу чего спорите?

Подобъект пустого базового класса может не занимать вообще никакой памяти (и обязан не занимать, если класс standard layout).
Most derived object занимает минимум 1 байт.
В остальном работает все как обычно.
Нас не должно заботить, как именно все это реализовано в компиляторе.

О чем спор?
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
03.08.2015, 15:34 #78
Цитата Сообщение от Ilot Посмотреть сообщение
Передача в функцию происходит по ссылке, т.е. мы передаем существующий объект без создания временного.
вы ошибаетесь.
вы передаете объект типа B.
а принимаете объект типа A&

срабатывает правило о приведении типов.

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

Цитата Сообщение от Ilot Посмотреть сообщение
Вопрос: если как вы говорите объект не может иметь нулевой размер то откуда в структуре взялся лишний байт?
нет никаких лишних байтов.
ещё раз: не путайте "структуру" с "подструктурой".


в статьях аля "низкоуровневый взгляд на наследование/полиморфизм/бла бла бла"

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

то есть:

C++
1
2
3
4
struct a{ int a; };
struct b{ int b; };
 
struct c : a, b { int c; };
следует воспринимсать, как:
C++
1
struct c : { int a,b, c; };
поймите уже наконец:
итоговый наследник наследует другие классы

компилятор для такого наследника копипастит по определенным правилам.
понимаете?

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

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

к структурам, из которых "как бы состоит класс" - это никакого отношения не имеет.

Добавлено через 1 минуту
Цитата Сообщение от ct0r Посмотреть сообщение
О чем спор?
это не совсем спор.

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

мой цемес в том, что "подобъекты" не имеют никакого отношения к "объектам".
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
03.08.2015, 15:40 #79
Цитата Сообщение от hoggy Посмотреть сообщение
мой цемес в том, что "подобъекты" не имеют никакого отношения к "объектам".
Ну вообще имеют. Давай посмотрим на терминологию стандарта.

1.8 [intro.object]/2 Objects can contain other objects, called subobjects. A subobject can be a member subobject (9.2), a base class subobject (Clause 10), or an array element. An object that is not a subobject of any other object is called a complete object.

1.8 [intro.object]/4 If a complete object, a data member (9.2), or an array element is of class type, its type is considered the most derived class, to distinguish it from the class type of any base class subobject; an object of a most derived class type or of a non-class type is called a most derived object.
2
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.08.2015, 15:46 #80
Цитата Сообщение от ct0r Посмотреть сообщение
Ilot, hoggy, я не понимаю, вы по поводу чего спорите?
Вообще-то это дискуссия. Спорят бабки на базаре (без обид - устоявшееся выражение).
hoggy, по-видимому мы не прийдем к общему мнению. Пусть каждый останется при своем. Потому как вопрос, как вы указали, свелся к
Цитата Сообщение от hoggy Посмотреть сообщение
"подобъекты" не имеют никакого отношения к "объектам"
А это уже вопрос формализма. Тут никто не может быть правым или ошибаться.

Не по теме:

ct0r, где же вы раньше были?

0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 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 фиг знает, нормально я объяснил или нет. Надеюсь поймете все
9
HighPredator
04.08.2015, 14:34
  #82

Не по теме:

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

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

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

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

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

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

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

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

в общем, нуля вы там никогда не получите.
потому что все подобные запросы выполняются в отношении объектов.
а не в отношении частей из которых состоит класс.
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
04.08.2015, 17:25 #84
Цитата Сообщение от hoggy Посмотреть сообщение
там лишь сказанно, что объект может содержать подобъект.
при этом, между "объектом" и "подобъектом" нигде знак равенства не ставится.
Там черным по белому написано несколько раз, что подобъект базового класса (base class subobject) это объект (object). И это не знак равенства, а отношение включения.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
04.08.2015, 17:28 #85
Цитата Сообщение от ct0r Посмотреть сообщение
Отсюда следует, что согласно формальной терминологии С++, объекты могут иметь нулевой размер.
отсюда следует, что согласно формальной терминологии, подобъектымогут иметь нулевой размер.
но подобъект - не есть объект.

вы там ещё полазийте по стандарту.
где то должно быть упоминание, согласно которому,
можно делать массивы из объектов любого типа.
и поэтому, размер объекта никак не может быть нулем.
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 1
04.08.2015, 17:31 #86
Цитата Сообщение от hoggy Посмотреть сообщение
вы там ещё полазийте по стандарту.
где то должно быть упоминание, согласно которому,
можно делать массивы из объектов любого типа.
и поэтому, размер объекта никак не может быть нулем.
Правильно, но отчасти. Размер не может быть нулем не для object, а для most derived object. Вот такая в стандарте терминология.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 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
только вы при этом обращаетесь именно что к объекту, как к нормальному объекту.
а не как к части класса.
0
S_el
2113 / 1633 / 308
Регистрация: 15.12.2013
Сообщений: 6,406
04.08.2015, 18:01 #88
Ferrari F1, это хорошая тема,я уже немало полезной и интересной информации узнал. Может, через пару лет, и вы из неё что-то сможете почерпнуть.
0
ct0r
Игогошка!
1777 / 679 / 42
Регистрация: 19.08.2012
Сообщений: 1,295
Завершенные тесты: 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.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 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,
память выделена не будет.
0
04.08.2015, 18:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.08.2015, 18:43
Привет! Вот еще темы с ответами:

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

Вот такой тест скинули на Джуна, пока еще не решил - PHP
Вот такой тест на джуна, пока еще не знаю даже с чего начать!))

Подскажите пожалуйста, как ответить на вопрос про полиморфизм в JAVA в достаточном объеме для прохождения собеседования - Java SE
Здравствуйте. Подскажите пожалуйста, как ответить на вопрос про полиморфизм в JAVA в достаточном объеме для прохождения собеседования....

Задача с собеседования - C (СИ)
Всем привет! Недавно был на собеседование. Было много вопросов по строкам. Такое объявление строки я не видел ни разу char *A; и,...


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

Или воспользуйтесь поиском по форуму:
90
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.