LINUX.ORG.RU

Задачки от yandex


5

3

Хотела задать вопрос в talks, но почему у меня нет такой возможности. Я недавно занялась изучением программирования на c++, поэтому прошу сильно не ругаться.

Не так давно наткнулась на вакансию разработчика в yandex, и там обнаружила несколько вопросов. Страница уже удалена, но доступна в кэше: http://webcache.googleusercontent.com/search?q=cache:l4nvA4HtP5gJ:company.yan...

Не укажите на мои ошибки в рассуждениях?

Вопрос 1

Перепишите код, устранив имеющиеся в нём проблемы, но не изменяя функцию main

class Foo {
 public:
  Foo(int j) { i = new int[j]; }
  ~Foo() { delete i; }

 private:
  int* i;
};

class Bar: Foo {
 public:
  Bar(int j) { i = new char[j]; }
  ~Bar() { delete i; }

 private:
  char* i;
};

void main() {
  Foo* f = new Foo(100);
  Foo* b = new Bar(200);
  *f = *b;
  delete f;
  delete b;
}

Здесь, я, как поняла, деструкторы должны быть виртуальными, должен быть описан оператор присваивания, а так же необходимо поле хранящее количество элементов, чтобы при копировании знать, какой длины массив? Или я что-то упустила?

Вопрос 2

В каких из следующих стандартных контейнеров худшее время поиска элемента по значению — O(log(n))?

 std::vector
 std::list
 std::deque
 std::set
 std::multiset
 std::unordered_set
 std::unordered_multiset
 сортированный std::vector
 сортированный std::list
 сортированный std::deque

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

Вопрос 3

Напишите код, преобразующий 32-битное целочисленное представление ip-адреса в строковое.

Догадываюсь, что что-то нужно куда-то сдвигать =)

Вопрос 4

Есть класс Bar, предназначенный для работы в многопоточной среде. Перечислите проблемы, которые вы видите в его реализации.

class Bar {
 public:
  void Add(int i, double d) {
    Locker auto_lock_d(m_doubles_);
    Locker auto_lock_i(m_integers_);
    integers_.push_back(i);
    doubles_.push_back(d);
  }

  bool Find(int i) {
    Locker auto_lock(m_integers_);
    if (std::find(integers_.begin(), integers_.end(), i) != integers_.end())
      return true;
    else
      return Find(double(i));
  }

  bool Find(double d) {
    Locker auto_lock(m_doubles_);
    return std::find(doubles_.begin(), doubles_.end(), d) != doubles_.end());
  }
    
 private:
  std::vector<int> integers_;
  std::vector<double> doubles_;
  Mutex m_integers_;
  Mutex m_doubles_;
};

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


Ответ на: комментарий от blogdron

для любой новой аппаратной платформы в первую очередь переносится именно Cи или его урезанный аналог

Почему переносится именно си? Потому что легаси заставляет. Про это я уже написал.

на си пишется много НОВОГО софта который без проблем можно написать на чём угодно

Можно примеры? Речь про индустрию, если что.

он тупо универсален и реально подойдёт для чего угодно

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

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Си живет и будет жить только благодаря легаси.

Си живет и будет жить благодаря простоте переноса компилятора на любую платформу. А также простоте самого языка.

vtVitus ★★★★★
()
Последнее исправление: vtVitus (всего исправлений: 1)
Ответ на: комментарий от vtVitus

Си простой? Вы его грамматику видели, стандарт читали? Компилятор пробовали написать?

Если gcc легко портируется на новую платформу, то потому, что фронтенд давно написан. А бекенд, который пишут, от языка не зависит.

А если компилятор пишут с нуля - то обычно не заморачиваются на «настоящий» си, а берут его часть, которую реально легко реализовать.

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Вы его грамматику видели, стандарт читали

в отличии от вас видел и читал.
компилятор пишется на раз.
я видел под разными системами несколько компиляторов, например, размер одного был 16 килобайт под k&r си и написали его с нуля за несколько дней.

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

vtVitus ★★★★★
()

1. утечка памяти в *f, и чуть ниже удаление удалённого.

drBatty ★★
()
Ответ на: комментарий от vtVitus

по-моему это везде будет работать, но 100% не гарантирую, как и всё в программировании, особенно для столь низкоуровневых языков.

а по моему, лучше тебе не лезть в сишечку.

drBatty ★★
()
Ответ на: комментарий от unsigned

Потому что легаси заставляет

Да, кончено, гораздо круче писать на сраной жаве, транслировать её через виртуалку и жрать 2/3 оперативной памяти.

Deleted
()
Ответ на: комментарий от vtVitus

видел и читал

Тогда непонятно, откуда берется утверждение о простоте. С C++ что ли сравниваете?

Примеры простого языка - это Паскаль или ML.

На раз пишется транслятор Схемы. Если её синтаксис положить на немного поправленную семантику си - вот тогда будет язык, который можно назвать легкопортируемым. И компилятор будет писаться не дни, а часы.

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

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Ладно, с часами я загнул. Но будет проще - это факт.

unsigned ★★★★
()
Ответ на: комментарий от unsigned

Если вам это неудобно, не объявляйте переменные таким образом, например придерживайтесь стандарта «одно объявление - одна переменная». Это вопрос стиля, а не синтаксиса. Синтаксис этого смешанного объявления выше, хотя и специально сделан неудобочитаемым, вполне логичен - «Тип int имеют: переменная a, результат разыменования b, элементы массива c, возвращаемое функцией f значение».

Cheater
()
Ответ на: комментарий от Cheater

Я понимаю логику этого объявления, в ней просто нет практического смысла. Достаточно того, что

специально сделан неудобочитаемым

unsigned ★★★★
()
Ответ на: комментарий от drBatty

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

vtVitus ★★★★★
()
Ответ на: комментарий от vtVitus

пиши где я не прав

union IP {
    unsigned int ip;
    struct {
      unsigned char d;
      unsigned char c;
      unsigned char b;
      unsigned char a;
    } ip2;
};

this

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

извини, но нигде не записано, что sizeof(unsigned) == 4*sizeof(char). Потому у тебя говнокод. Смирись с этим.

drBatty ★★
()
Ответ на: комментарий от vtVitus

вот анонимус в конце прав, четко по делу и без наездов, а ты пиздобол и смирись с этим.

и да, ты написал быдлокод, тебе указали, что ты — быдлокодер. Если ты про этот пост, то его автор тоже не прав, дело тут не только в выравнивании. Тип unsigned может иметь ЛЮБОЙ размер в char'ах. Нам известно только то, что он НЕ МЕНЬШЕ 1(char). А вот сколько он — 1, 3, или 10 — никто не знает. Сейчас равен 4. Двадцать лет назад было 2. Завтра скорее всего будет 8.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.