Задать вопрос
  • Есть идея, простая как валенок, с чего начать?

    Alexx_ps
    @Alexx_ps
    1) Вы параноик.
    2) Что за падонкоффский язык?
    3) Так уж на Руси повелось, что в начале предложений принято ставить заглавную букву!
    4) Ну не украдут разработчики вашу идею сейчас, значит украдут через месяц после вашего запуска, сделают более грамотный маркетинг и вы все равно останитесь ни с чем.
    5) Инвесторы херней не занимаются.
    Ответ написан
    Комментировать
  • Возврат наушников в магазин

    @GaJetFan
    Если упаковка не распечатана, то проблем не должно быть с возвратом. А если же вы их уже одевали, то в зависимости от того, в каком магазине вы покупали, проблемы будут или нет. (именно про горбушку ничего сказать не могу — давно там из аудиотехники ничего не покупаю)

    Суть такова: Наушники причислены к чуть ли не к средствам личной гигиены. Т.е. как вы не сможете отдать в магазин поношенное два дня нижнее белье, так и наушники — поносили некоторое время, значит они были у вас в ушах или на голове (в зависимости от формфактора наушников) — значит вернуть нельзя.

    Но все же есть магазины, в которых изначально оговорена возможность возврата наушников в течение двух недель (но за такую возможность надо дополнительно платить). Точнее знаю только один такой магазин — плеер.ру

    Советую не отчаиваться сразу, а поехать и попробовать обменять. Если начнут приставать с вопросами почему возвращаете — можно попытаться сделать акцент на неправильном звучании наушников (даже если такой проблемы нет) — обычно продавцы в таких магазинах плохо разбираются в звуке и такой вариант может «прокатить».

    Но, на будущее, советую брать наушники в магазинах, в которых оговорена возможность возврата наушников в течение двух недель без объяснения причин — не понравилось — сдали обратно. Или же в магазинах, где наушники дают послушать перед покупкой — например, в ДХ.
    Ответ написан
    6 комментариев
  • Возврат наушников в магазин

    @bondbig
    Я возвращал пару раз, даже вскрытые. Без вопросов.
    Ответ написан
    Комментировать
  • Создание Garbage Collector-а

    @lesha_penguin
    Отвечая на вопрос, хочу поделиться одним хорошо себя зарекомендовавшим решением. Извиняюсь что для комментария «много букв», ибо только что хотел написать это как топик, но увы, у меня кармы пока нема…

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

    Вроде бы «задача для школьников» написал структуры данных со всеми полями для вершин и ребер графа, а дальше вроде все просто, «все как по учебнику» — выделяй для них память из кучи с помощью malloc/new и проставляй указатели.

    Проблема возникает когда мы, поработали с данным графом и он нам больше не нужен. Кажущаяся простая задача «взять и освободить память для всех объектов», т.е. для каждого объекта вызвать соответствующий free/delete причем один один и только один раз, на деле оказывается не просто сложной а в общем случае NP-сложной. Т.е. вся предыдущая работа работа с этим хитрым графом может показаться «цветочками» по сравнению с попыткой найти в каком же порядке обойти элементы чтобы никого не забыть (ибо иначе утечка памяти) и вызвать освобождение каждого элемента только один раз (ибо при двойном освобождении мы нарушим логику других потоков нашей программы).

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

    Однако давайте посмотрим в корень проблемы. Проблему сложности поэлементного освобождения как таковую порождает само поэлементное выделение обьектов из динамической памяти (кучи). Кстати, это в добавок ко всем остальным проблемам динамической памяти таким как фрагментация, замедление операций выделения/освобождения когда динамическая память представляет собой кашу из сотен тысяч фрагментов разного размера вперемешку с свободными элементами тоже разного размера (а именно такую адскую кашу представляет собой динамическая память у любителей STL).

    Решение может быть простым и изящным — аллокатор памяти без поэлементного освобождения. Звучит сложно, но реализация проста.

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

    Сам чанк имеет следующую структуру:

    struct _alloc_pool_mem_chunk{ // чанк пула-аллокатора без поэлементного освобождения
      size_t size;  // размер данных чанка
      size_t curr;  // текущее заполнение чанка
      struct _alloc_pool_mem_chunk*next; // указатель на следующий чанк нашего пула
      uint8_t data[0]; // данные чанка
      };
    


    Выделение памяти из такого чанка элементарно:
    static void *memchunk_alloc_from_chunk(struct _alloc_pool_mem_chunk*ch,size_t s){
      if(!ch||!s){return 0;} // простая проверка
      if( (ch->size-ch->curr) < s){return 0;} // у нас в чанке свободно (ch->size-ch->curr) байт
      void *rv=&ch->data[ch->curr];
      ch->curr+=s; // сдвигаем на s байт
       return rv;
      }
    


    Если в чанке нет места для объекта, мы просто добавляем еще онин чанк:

    static struct _alloc_pool_mem_chunk *memchunk_add_chunk(struct _alloc_pool_mem_chunk **chp,size_t chunk_size){
      struct _alloc_pool_mem_chunk*ch=malloc(sizeof(struct  _alloc_pool_mem_chunk)+chunk_size);  // выделяем чанк 
      if(!ch){return 0;}
      ch->curr=0;
      ch->size=chunk_size;
      ch->next=*chp; // сцепляем чанки в связный список
      *chp=ср;
      return ch;
      }
    


    Вся процедура выделения памяти из такого аллокатора в простейшем виде:

    void *memchunk_alloc(struct _alloc_pool_mem_chunk **chp,size_t s,size_t chunk_size){
     void *rv; 
     static struct _alloc_pool_mem_chunk *ch=*chp;
     if((rv=memchunk_alloc_from_chunk(ch,s))){return rv;} // выделяем из текущего чанка
     if(!(ch=memchunk_add_chunk(chp,chunk_size))){return 0;} // не удалось добавить чанк-облом
     rv=memchunk_alloc_from_chunk(ch,s);  // выделаем из нового чанка
     return rv;
      }
    


    Функция освобождения всего пула-просто обходим все чанки:

    void memchunk_free_all(struct _alloc_pool_mem_chunk **chp){
      struct _alloc_pool_mem_chunk *ch=*chp;
      while(ch){
         struct _alloc_pool_mem_chunk *chn=ch->next;
         free(ch);
         ch=chn;
         }
      }
    


    Достоинства:
    • Чрезвычайная простота реализации. Даже школьник способен с первого раза за несколько минут написать безошибочно такой аллокатор. Кстати код выше я не копипастил а просто набрал по памяти (из ошибок могут быть очепятки).
    • Низкий overhead. всего 12/24 байта (x86/x86_64) на чанк.
    • Не фрагментирует память. Существенное достоинство, особенно когда элементов сотни тысяч.
    • Выделение элемента работает быстрее, в разы быстрее чем malloc/new. (Выделение памяти для элемента из чанка 3 строки). Освобождение элемента — вообще nop!
    • Если нам вдруг захочется threadsafe — мы легко получим всего лишь заменив запись ch->curr+=s на cmpxchg и добавив какой-нибудь легковесный примитив типа spinlockа на добавление чанка.
    • У нас свой быстрый и легковесный garbage collector с коммандой «освободи все». Пройти по (NB: небольшому) списку чанков — это не считать ссылки в миллионах объектов.
    • Да, контроль занятой памяти нашей хитрой структурой. Мы всегда можем быстро сказать, что например этот граф занимает 3.5Mb, просто пробежавшись по чанкам.
    • Проверенно лично мною на десятке highload-проектов.


    Недостатки:
    • А они бывают только в тех случаях, если этот аллокатор использовать для непредусмотренных целей:)


    P.S.: Желаю всем хабраюзерам приятных экспериментов.
    Ответ написан
    3 комментария
  • Циклы или рекурсия?

    @sergei-grigorev
    Все зависит от задачки. Порою достаточно простого цикла, с ним и работать проще и нет проблем со стеком. Еще, лучше все таки в цикле решать задачи, где результат следующего полностью зависит от результата предыдущего (например, факториал).

    При других задачках (например, обход вложенных каталогов), когда при этом у каждого имеется ряд своих отдельных переменных (например, количество файлов в данном каталоге), или асинхронных потоков, то поддерживать легче будет рекурсию. Да и рекурсия в данном случае будет удобнее, потому что обход одного каталога совсем не зависит от результатов обхода другого соседнего каталога, и они могут работать параллельно, независимо друг от друга. А затем в конце просто объединяют все свои результаты.

    Еще рекурсия будет эффективна, если рекурсивная функция кешируемая, например, она запоминает результат и при следующем запросе просто возвращается кешированный вариант.
    Ответ написан
    2 комментария
  • Книги по операционным системам?

    couatl
    @couatl
    Таненбаума уже посоветовали.
    Могу посоветовать еще очень хороший комплект из 2х томов: Дейтел «Операционные системы».

    Еще нам по курсу советовали Соломон, Руссинович «Внутреннее устройство Microsoft Windows». Интересно, даже полезно, но слишком зашито под Windows, но некоторые полезные вещи можно вычитать. Также очень интересен блог Руссиновича — blogs.technet.com/b/mark_russinovich/
    Ответ написан
    Комментировать
  • Как оформить своё сообщение, чтобы было понятно, что это ирония?

    akalend
    @akalend
    программирую
    Не у всех есть чувство юмора, так что не обижайся, если кто-то что-то не допонимает…
    меня много раз за это минусовали, но ничего — живой пока :)
    смотри на мир — проще.

    и еще здесь присутствует стадное чувство — один дурак заминусует, и за ним все стадо…
    Ответ написан
    Комментировать
  • Помогите "изобрести" комментарии заново

    dudeonthehorse
    @dudeonthehorse
    Email Developer
    Ну раз ни то, ни се, тогда принцип q&a на хабре. Дерево с глубиной в 1 ступень.
    Ответ написан
    4 комментария
  • Почему на Хабре кнопка «опубликовать» такая большая?

    optemist
    @optemist
    Присоеденяюсь. Каждый раз боюсь ее случайно нажать, во время работы над статьей. А еще было бы неплохо спросить подтверждение перед публикацией, вдруг я ее нечаянно нажал.
    Ответ написан
    4 комментария
  • Что должен знать настоящий программист?

    Zorkus
    @Zorkus
    Добавлю к перечисленному — еще настоящий программист должен (ящитаю) знать хотя бы основные структуры данных (массив, связный список, стек, очередь, деревья, графы) и алгоритмы, все это не привязываясь к конкретному языку. А так же понимать хотя бы минимально понятие ассимптотической сложности (О-большое) по времени и по памяти.

    Без этого трудно писать не-быдлокод.
    Ответ написан
    Комментировать
  • Что должен знать настоящий программист?

    taliban
    @taliban
    php программист
    Это на самом деле риторический вопрос, нет определенных критериев, в некоторых яп нет замыканий, но там есть настоящие программисты.
    Настоящий программист должен уметь думать и интересоваться своей работой. Если есть эти два критерия, то он сам найдет и замыкания, и бинарный поиск итд.
    Ответ написан
    Комментировать
  • Учебник по информатике

    VBart
    @VBart
    Решите для начала, что вы действительно хотите знать. Если операционные системы, то гуглите на тему книжек Таненбаума. Если железо, опять же какое, какая архитектура. Это уже будут совсем другие книжки.
    Ответ написан
    7 комментариев
  • Сколько дал вам университет знаний?

    Vas3K
    @Vas3K
    Литра три!
    Странный вопрос, на него невозможно ответить. Каждый получил столько, сколько хотел. Кто-то параллельно читал книжки и пробовал все на практике, думал как это применить в работе, другие же наоборот, ставили себе цель «лишь бы сдать», поэтому зубрили основные формулы. При том и те и другие есть у меня в группе.

    P.S.: Ну вот, дописал и только заметил, что отвечаю знакомому из университета. Неужели тебе не нравится? Ты на какой специальности, чет я подзабыл. Лично я реально много получил даже за половину университета, пусть я и знал много, но это структурирует по самое не могу.
    Ответ написан
    5 комментариев
  • плагины для удобства работы в Visual Studio 2010

    Kalantyr
    @Kalantyr
    Resharper
    Ответ написан
    Комментировать
  • Есть ли здесь бывшие олимпиадники? Как олимпиады помогли Вам?

    @tangro
    Диплом призера государственной олимпиады дал мне бюджетное место в ВУЗе. Диплом победителя внутривузовской олимпиады — повышенную стипендию (200%).

    С психологической точки зрения олимпиады дали мне такие вещи как:
    1. Веру в том, что нерешаемых задач нет. Надо просто еще чуть-чуть подумать.
    2. Принцип «сначала делаем то, что знаем, потом — то, что не знаем». Очень помогает.
    3. Чувство того, что всегда есть кто-то впереди тебя и стремление его догнать и перегнать.

    С точки зрения полезности олимпиадных знаний — почти ничего. Нет, ну конечно, кое-какие познания в области дискретной математики, теории вероятности и т.д. остались, но в целом олимпиадное программирование и промышленное программирование не связаны никак. Это как фигурное катание и хоккей — и там и там вроде бы есть коньки и лёд, но вот методы их использования и конечные цели очень отличаются.
    Ответ написан
    8 комментариев
  • Какие есть в сети интернет ресурсы для любителей (именно любителей) программировать?

    @shalex9154
    Если хочешь научится основным алгоритмов, тот этот сайт просто находка informatics.mccme.ru.
    Ответ написан
    Комментировать
  • Какой размер метода/функции "в экранах" считается нормальным?

    Kalantyr
    @Kalantyr
    Смысл этого правила в том, чтобы метода был обозрим с одного взгляда.

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

    Кроме количества строк есть еще длина строк, ее тоже лучше ограничивать. Я давно пишу на C# и часто делаю внутри кода отступы пустыми строками, вставляю регионы (#region). Отступы немного увеличивают количество строк, а регионы — существенно сокращают (в свернутом состоянии).

    Кроме того, у меня широкоэкранный монитор повернут на 90 градусов, так что на один экран входит два обычных :)
    Ответ написан
    Комментировать