тестовые вопросы
От: Alexander Pazdnikov  
Дата: 20.06.12 08:04
Оценка:
Здравствуйте, Коллеги.

Прошу поправить мои ответы на несколько тестовых вопросов.

Спасибо.



.Q
1. Является ли язык C строгим подмножеством языка C++?

.A
По-моему, нет.
По крайней мере, усиленный контроль типов в C++ требует от большинства программ на С доработки.

.Q
4. Каков размер следующей структуры? Почему?

struct S
{
int i;
void *v;
char c;
long l;
};

.A
зависит от разрядности процессора и от принятого выравнивания адресов.

ARM — (sizeof(int) = 4, sizeof(void *) = 4, alignment = 4) — 16 байт
x86 (sizeof(int) = 4, sizeof(void *) = 4, alignment = 4) — 16 байт
x86_64 (sizeof(int) = 4, sizeof(void *) = 8, alignment = 4) — 20 байт
ia64 (sizeof(int) = 8, sizeof(void *) = 8, alignment = 8) — 32 байт

.Q
8. Предположим, есть реализация dequeue в виде двусвязного списка (то
есть есть указатели на предыдущий и следующий элементы). А
возможна ли реализация, где для связи узлов используется только
одно слово вместо двух (то есть мы хотим сэкономить одно слово
размера sizeof(struct node *))?
.A
Полагаю, речь идёт о циклическом буфере или контейнере где есть указатель на начало и указатель на конец, элементы включают указатель только на следующий элемент. Проход односторонний, с конца в начало.

.Q
9. Предположим, что в многопоточной программе в одном потоке
выполняется код

a = 3;
b = 1;

а в другом потоке

if (b == 1)
sum += a;

(оба потока видят одни и те же а и b, блокировок нет). Если
условие выполнится, то на сколько увеличится sum?

.A
либо на 3, либо на 6.
Re: тестовые вопросы
От: Abyx Россия  
Дата: 20.06.12 08:19
Оценка: 2 (1)
Здравствуйте, Alexander Pazdnikov, Вы писали:

AP>Здравствуйте, Коллеги.


AP>Прошу поправить мои ответы на несколько тестовых вопросов.


AP>Спасибо.




AP>.Q

AP>1. Является ли язык C строгим подмножеством языка C++?

AP>.A

AP>По-моему, нет.
AP>По крайней мере, усиленный контроль типов в C++ требует от большинства программ на С доработки.

действующие стандарты С11 и С++11 имеют различные синтаксические конструкции.
могу ошибаться, но уже как минимум начиная с С99/С++98 С не является подмножеством С++

AP>.Q

AP>4. Каков размер следующей структуры? Почему?

AP> struct S

AP> {
AP> int i;
AP> void *v;
AP> char c;
AP> long l;
AP> };

AP>.A

AP>зависит от разрядности процессора и от принятого выравнивания адресов.

AP>ARM — (sizeof(int) = 4, sizeof(void *) = 4, alignment = 4) — 16 байт

AP>x86 (sizeof(int) = 4, sizeof(void *) = 4, alignment = 4) — 16 байт
AP>x86_64 (sizeof(int) = 4, sizeof(void *) = 8, alignment = 4) — 20 байт
AP>ia64 (sizeof(int) = 8, sizeof(void *) = 8, alignment = 8) — 32 байт

sizeof(S), который не меньше суммы sizeof ее членов. выравнивание не указано, и компилятор может использовать любое выравнивание.
btw, в своем ответе Вы забыли про alignment=1


AP>.Q

AP>8. Предположим, есть реализация dequeue в виде двусвязного списка (то
AP> есть есть указатели на предыдущий и следующий элементы). А
AP> возможна ли реализация, где для связи узлов используется только
AP> одно слово вместо двух (то есть мы хотим сэкономить одно слово
AP> размера sizeof(struct node *))?
AP>.A
AP>Полагаю, речь идёт о циклическом буфере или контейнере где есть указатель на начало и указатель на конец, элементы включают указатель только на следующий элемент. Проход односторонний, с конца в начало.

тогда это не double-ended queue, раз мы не можем удалять элементы с конца за О(1)

AP>.Q

AP>9. Предположим, что в многопоточной программе в одном потоке
AP> выполняется код

AP> a = 3;

AP> b = 1;

AP> а в другом потоке


AP> if (b == 1)

AP> sum += a;

AP> (оба потока видят одни и те же а и b, блокировок нет). Если

AP> условие выполнится, то на сколько увеличится sum?

AP>.A

AP>либо на 3, либо на 6.

для начала надо определить исходные значения a и b.
поток #2 может выполниться до потока #1,
либо сначала выполнится b = 1; потом поток #2, потом a = 3;

откуда взялось 6 я не понял, может вы имели ввиду что код выполняется в цикле? так и надо писать %)
In Zen We Trust
Re[2]: тестовые вопросы
От: Alexander Pazdnikov  
Дата: 20.06.12 08:49
Оценка:
Здравствуйте, Abyx, Вы писали:

A>sizeof(S), который не меньше суммы sizeof ее членов. выравнивание не указано, и компилятор может использовать любое выравнивание.

A>btw, в своем ответе Вы забыли про alignment=1
спасибо, а на практике это 8-битные процы, аля atmega, z80, i8080?

A>тогда это не double-ended queue, раз мы не можем удалять элементы с конца за О(1)


В концах можем удалять и добавлять элементы за O(1), для этого есть указатели head и tail.


A>откуда взялось 6 я не понял, может вы имели ввиду что код выполняется в цикле? так и надо писать %)


Имел в виду, что при проходе обоих потоков через этот код, sum суммарно увеличится либо на 3, либо на 6. Зависит от переключения контекста в другой поток при выполнении sum += a.
полагаю, что b == 1 и a == 3 в обоих потоках при любом раскладе.
Re: тестовые вопросы
От: vadfromnu  
Дата: 20.06.12 08:59
Оценка: 8 (2)
Здравствуйте, Alexander Pazdnikov, Вы писали:

AP>.Q

AP>8. Предположим, есть реализация dequeue в виде двусвязного списка (то
AP> есть есть указатели на предыдущий и следующий элементы). А
AP> возможна ли реализация, где для связи узлов используется только
AP> одно слово вместо двух (то есть мы хотим сэкономить одно слово
AP> размера sizeof(struct node *))?
AP>.A
AP>Полагаю, речь идёт о циклическом буфере или контейнере где есть указатель на начало и указатель на конец, элементы включают указатель только на следующий элемент. Проход односторонний, с конца в начало.

Похоже, спрашивается про XOR-связный список.

AP>.Q

AP>9. Предположим, что в многопоточной программе в одном потоке
AP> выполняется код

AP> a = 3;

AP> b = 1;

AP> а в другом потоке


AP> if (b == 1)

AP> sum += a;

AP> (оба потока видят одни и те же а и b, блокировок нет). Если

AP> условие выполнится, то на сколько увеличится sum?

AP>.A

AP>либо на 3, либо на 6.

Без барьеров памяти на 3 или значение a до изменения.
Re[3]: тестовые вопросы
От: Abyx Россия  
Дата: 20.06.12 09:10
Оценка:
Здравствуйте, Alexander Pazdnikov, Вы писали:

AP>Здравствуйте, Abyx, Вы писали:


A>>sizeof(S), который не меньше суммы sizeof ее членов. выравнивание не указано, и компилятор может использовать любое выравнивание.

A>>btw, в своем ответе Вы забыли про alignment=1
AP>спасибо, а на практике это 8-битные процы, аля atmega, z80, i8080?
на практике это #pragma pack(1) и например передача структур по сети

A>>тогда это не double-ended queue, раз мы не можем удалять элементы с конца за О(1)


AP>В концах можем удалять и добавлять элементы за O(1), для этого есть указатели head и tail.

как удалить с конца если мы не знаем предыдущий элемент?

A>>откуда взялось 6 я не понял, может вы имели ввиду что код выполняется в цикле? так и надо писать %)


AP>Имел в виду, что при проходе обоих потоков через этот код, sum суммарно увеличится либо на 3, либо на 6. Зависит от переключения контекста в другой поток при выполнении sum += a.

AP>полагаю, что b == 1 и a == 3 в обоих потоках при любом раскладе.

Вы имеете ввиду такой код?
int sum = 0;
int a, b;

void thread_fn()
{
  a = 3;
  b = 1;

  if (b == 1)
    sum += a;
}

int main()
{
  thread t1(thread_fn);
  thread t2(thread_fn);
  t1.join();
  t2.join();
  return sum;
}


так sum всегда будет 6, в любом потоке перед if a и b будут 3 и 1
In Zen We Trust
Re[4]: тестовые вопросы
От: B0FEE664  
Дата: 20.06.12 09:23
Оценка: 1 (1)
Здравствуйте, Abyx, Вы писали:

A>>>sizeof(S), который не меньше суммы sizeof ее членов. выравнивание не указано, и компилятор может использовать любое выравнивание.

A>>>btw, в своем ответе Вы забыли про alignment=1
AP>>спасибо, а на практике это 8-битные процы, аля atmega, z80, i8080?
A>на практике это #pragma pack(1) и например передача структур по сети
или опции компилятора

A>Вы имеете ввиду такой код?

A>
A>int sum = 0;
A>int a, b;

A>void thread_fn()
A>{
A>  a = 3;
A>  b = 1;

A>  if (b == 1)
A>    sum += a;
A>}

A>int main()
A>{
A>  thread t1(thread_fn);
A>  thread t2(thread_fn);
A>  t1.join();
A>  t2.join();
A>  return sum;
A>}
A>


A>так sum всегда будет 6, в любом потоке перед if a и b будут 3 и 1

Даже при выполнении этих ниток на двух разных процессорах?
И каждый день — без права на ошибку...
Re[5]: тестовые вопросы
От: Abyx Россия  
Дата: 20.06.12 09:45
Оценка: 1 (1)
Здравствуйте, B0FEE664, Вы писали:

A>>Вы имеете ввиду такой код?

A>>
A>>int sum = 0;
A>>int a, b;

A>>void thread_fn()
A>>{
A>>  a = 3;
A>>  b = 1;

A>>  if (b == 1)
A>>    sum += a;
A>>}

A>>int main()
A>>{
A>>  thread t1(thread_fn);
A>>  thread t2(thread_fn);
A>>  t1.join();
A>>  t2.join();
A>>  return sum;
A>>}
A>>


A>>так sum всегда будет 6, в любом потоке перед if a и b будут 3 и 1

BFE>Даже при выполнении этих ниток на двух разных процессорах?

а, понял.
только непонятно зачем там тогда if и присваивания %)
In Zen We Trust
Re[4]: тестовые вопросы
От: Alexander Pazdnikov  
Дата: 20.06.12 09:54
Оценка:
Здравствуйте, Abyx, Вы писали:

A> if (b == 1)

A> sum += a;
A>}

По идее не всегда.
Операция sum += a не является атомарной.

псевдокод

tmp = sum + a;
/* здесь контекст переключается на второй поток, во втором потоке значение sum будет старым */
sum = tmp;

то в таком случае sum == 3
Re[4]: тестовые вопросы
От: Alexander Pazdnikov  
Дата: 20.06.12 09:57
Оценка:
Здравствуйте, Abyx, Вы писали:

A>>>тогда это не double-ended queue, раз мы не можем удалять элементы с конца за О(1)


AP>>В концах можем удалять и добавлять элементы за O(1), для этого есть указатели head и tail.

A>как удалить с конца если мы не знаем предыдущий элемент?

да, действительно.
Re[6]: тестовые вопросы
От: Alexander Pazdnikov  
Дата: 20.06.12 10:05
Оценка:
Здравствуйте, Abyx, Вы писали:

A>только непонятно зачем там тогда if и присваивания %)


то же не могу понять, зачем if и присваивания?
Re[4]: тестовые вопросы
От: Mr.Delphist  
Дата: 20.06.12 10:18
Оценка: +1
Здравствуйте, Abyx, Вы писали:
A>на практике это #pragma pack(1) и например передача структур по сети

Плюс можно добавить, что доступ к данным с адресом, не выровненным по машинному слову, либо менее эффективен (как у x86), либо падает в рантайме (некоторые микроконтроллеры, плюс было ещё что-то из процессоров старой школы наподобие Alpha)
Re[5]: тестовые вопросы
От: Abyx Россия  
Дата: 20.06.12 10:27
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Здравствуйте, Abyx, Вы писали:

A>>на практике это #pragma pack(1) и например передача структур по сети

MD>Плюс можно добавить, что доступ к данным с адресом, не выровненным по машинному слову [...] либо падает в рантайме (некоторые микроконтроллеры, плюс было ещё что-то из процессоров старой школы наподобие Alpha)


у arm тоже падает, если используется инструкция требующая выравнивание
In Zen We Trust
Re[7]: тестовые вопросы
От: Erop Россия  
Дата: 20.06.12 10:41
Оценка: 2 (1)
Здравствуйте, Alexander Pazdnikov, Вы писали:

AP>то же не могу понять, зачем if и присваивания?



За барьерами. В самом общем случае С++ не гарантирует, что при оптимизации будет сохранено наблюдаемое поведение, если смотреть из другой нити. Например, компилятор может переупорядочить эти присваивания.
Мало того, их может переупорядочить не только оптимизатор компилятора, но и процессор тоже.

В общем то, что из другой нити уже видно, что b == 1 не гарантирует, что из неё же уже видно, что а == 3...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.