Первый способ проще тем, что кода значительно меньше и он линеен. Меньше кода — меньше ошибок и времени для разработки.
Вместо двух состояний (ошибка, успешное завершение) при использовании неблокирующих сокетов добавляется третье — «выполнение операции без блокирования невозможно», при котором нужно прервать действие и перейти в режим ожидания готовности. А это дополнительная проверка после каждой операции с сокетами.
Как следствие — при использовании неблокирующих операций придётся вместо одной функции писать целый класс — машину состояний, сохраняющей точку входа. Желающие помучиться с отладкой, но писать в первом стиле могут ещё использовать нити.
Во времена, когда апач начинал развиваться, правильных архитектурных решений попросту ещё не существовало. Например, во времена релиза Apache 2.0 не было ни libevent, ни epoll, только select, который обладал очень плохой масштабируемостью.
А я перешёл на 5 ГГц, заменив при этом карточки в ноутбуках на быстрые двухдиапазонные.
При скорости передачи данных 35-40 мбайт/сек отпала необходимость в проводе.
А ещё можно подождать с отправкой данных до тех пор, пока буфер не освободится, что в подавляющем большинстве случаев обычно и делают. Если данные — это большой файл, то передачей данных придётся заниматься нам самим, а не лезть в системные буферы и уж тем более отказывать клиенту в обслуживании, потому что захотел слишком большой файл.
И основных решения тут два:
1. Каждому соединению — по потоку, а то и по два (чтение и запись), используя блокирующие операции чтения и записи данных.
2. Использование select, epoll, libevent, неблокирующих операций и прочих радостей жизни.
Второй способ сильно эффективнее, но первый сильно проще в реализации, поэтому с него и нужно начинать изучение.
Кстати, Apache под Windows пользовался первым способом — создавал 100 потоков и обрабатывал каждый запрос в своём потоке.
Недостаток такой реализации — это однопоточность сервера. Если хоть какое-то соединение с клиентом «подвиснет» и будет переполнен его исходящий буфер, то сервер просто зависнет на вызове write.
Решения данной проблемы:
1. Создание отдельного потока для каждого клиента. Недостаток: необходимость понимания механизмов синхронизации, низкая эффективность при большом числе соединений. Новичкам будет тяжело разобраться.
2. Использование select также и для записи в сокеты. Думаю, в данном случае самое простое решение.
3. Использование более высокоуровневых языков с поддержкой асинхронного программирования.
Вообще есть разные функции отправки и приема, к примеру send и recv вместе с сообщением шлют еще и флаг подтверждения, а функции read и write не требуют подтверждения, то есть сообщение может потерять байты при отправке и это не будет зафиксировано.
Это не так: read() и write() эквивалентны recv() и send() с нулевыми флагами.
Ну и ещё один момент: код очень разрозненный, фрагментарный. Новичку была бы полезна ссылка на репозиторий.
Если на странице изменят размер, тогда изображения сверху никак не будут влиять на отображение текущих изображений — ничего не уедет при уменьшении размера — это большой плюс. А при скролле наверх размер будет фиксирован, в худшем случае появится горизонтальный скролл. Но такие случаи будут редки.
Вариант с сохранением HTML и восстановлением эвентов вполне годен.
Идея динамически подгружаемого контента возникала тогда, когда сами сайты стали настолько тяжёлыми (как по общему контенту, так и по заскриптованности), что собственно полезное содержимое стало занимать небольшую часть от всего сайта, когда загрузка страницы заново с парсингом и выполнением толстых JS-фреймворков стала менее удобна, чем просто догрузка контента.
Но вместо того, чтобы облегчить страницу, ускорив её загрузку, многие выбирают второй путь: добавить ещё один фреймворк для скроллинга и хоть как-то заставить его работать.
Вообще говоря, идея турков мне даже нравится: это может уменьшить ценность телефонов для воров, которым телефон нужен не ради запчастей. Но при этом должен будет нормально работать механизм разблокировки телефона при смене оператора, например.
По-моему, никакой выгрузки картинок не происходит, а имеет место оптимизация в самом браузере — не хранятся в памяти невидимые декодированные изображения.
Ради интереса проскроллил 2000 изображений в выдаче и посмотрел в DOM. Результат — в главном окне 2000 объектов с кучей потомков, одих из которых — img. И каждый раз при модификации DOM браузеру приходится рендерить страницу, учитывая это. То есть длительный скроллинг приводит к разбуханию страницы и высокой нагрузке на CPU. Самое весёлое — попробовать изменить размер страницы и смотреть, как пыжится браузер и как всё куда-то уезжает.
Я бы оптимизировал следующим образом:
1. После загрузки определённого числа изображений (например, 20-30 штук) помещал бы их в один большой прямоугольный блок, размер которого был бы фиксирован и не менялся. Блоки должны располагаться вертикально. В этом случае при изменении размера страницы тормозов будет существенно меньше, а последующие выдачи результатов будут выводиться под обновлённый размер страницы.
2. При пропадании блока из области видимости очищал бы из него вообще всё, сохраняя только минимально необходимый набор метаданных, достаточных для восстановления содержимого блока.
3. При появлении блока в области видимости восстанавливал бы его содержимое.
Да, именно так: на ощущение духоты влияет, в первую очередь, температура и влажность. Поэтому люди, находясь в помещении со сплит-системой с выставленными 18-20, не чувствуют духоты даже при зашкаливающем CO2.
Да, тоже об этом думал. Выдачи данных по USB там тоже нет.
Вот и остаются варианты:
1. Паять датчик на коленке (с сомнительной надёжностью).
2. Ломать рабочие устройства.
3. Покупать втридорога специализированные датчики для умного дома.
В случае с кондиционером эффект идёт просто от циркуляции воздуха в комнате.
При высоких значениях температуры (а 28.5 — это очень жарко) естественная циркуляция (подъём тёплого выдыхаемого воздуха вверх) ослабевает, поэтому духота нарастает быстрее. Вот кондиционер частично спасает от этого.
Моё мнение: программист-олимпиадник — это, в первую очередь, математик-теоретик, а не программиист-практик. Разница почти как между разработчиком и системным администратором. Со стороны обоих незаывают программистами.
Ошибка и работодателей и олимпиадников заключается в том, что умения «могу разрабатывать алгоритмы для решения сложных задач» и «могу эффективно писать код» — это разные умения. Из одного не обязательно следует другое.
Лично я пошёл в науку: поначалу по инерции, потом оказалось, что это не так уж и плохо по деньгам выходит.
Курс антибиотика строго фиксирован. Уменьшать, равно как и увеличивать его, опасно.
Как я это понимаю: организм человека является постоянным носителем многих патогенных бактерий, постоянно сдерживаемых иммунитетом. В определённых условиях иммунитет перестаёт сдерживать бактерии (ослабление иммунитета, либо внесение большого числа бактерий извне), в результате чего человек заболевает.
Применение антибиотиков позволяет помочь организму справиться с бактериальными инфекциями, путём снижения концентрации бактерий до уровня, который не представляет опасности для человека.
При недостаточном курсе болезнь недолечивается (остаётся слишком много бактерий), что чревато осложнениями. Убивается недостаточное число чувствительных бактерий, поэтому иммунитет недостаточно эффективно борется с резистетными бактериями, в итоге по завершении болезни их доля становится выше.
При нормальном курсе убивается достаточное число чувствительных бактерий, чтобы с остальными успешно справился иммунитет.
При избыточном курсе антибиотиков основной вред идёт от подавления микрофлоры кишечника и побочных эффектов. Возможно увеличение концентрации резистентных бактерий при иммунодефиците.
При применении антибиотика без показаний (заболевания) изменяется соотношение постоянно присутствующих бактерий в организме.
Очевидно же, что подобные исследователи наносят вред бизнесу: приходится оплачивать время сотрудников на исправление проблем, терять убытки вследствие падения репутации от публикаций о найденных уязвимостях. Вот поэтому бизнес и огрызается. Когда вопрос касается денег — мораль отходит на второй план.
А раз нет юридической разницы между исследовательским и злонамеренным поиском уязвимостей, то зачем строить из себя белого и пушистого? Например, анонимно выложить уязвимость в паблик, а затем подать коллективный иск от пострадавших пациентов.
Видимо, есть какие-то лазейки, раз arXiv, ResearchGate всё ещё существуют и позволяют обмениваться научными статьями. Либо крупные издательства не считают необходимым их давить, как sci-hub.
Размер статьи был 6 страниц. В номерах 5-летней давности бывали статьи и короче. Специально её никто не сокращал. Больше сделать можно было бы только наливая воды, например, вставив доказательство теоремы, на которую была только ссылка.
> Скажите, а такая практика в отношении публикаций в вашей области широко распространена или это лишь один из немногих примеров?
Нет, это только один пример, обычно редакторы адекватнее.
> Можно ли было опубликовать статью в журнале сопоставимого или хотя бы не сильно худшего уровня без расходов со стороны авторов?
Того же уровня — нет, без расходов — да.
> Как в итоге поступили со статьей?
Отправим в другой журнал уровнем пониже.
Вместо двух состояний (ошибка, успешное завершение) при использовании неблокирующих сокетов добавляется третье — «выполнение операции без блокирования невозможно», при котором нужно прервать действие и перейти в режим ожидания готовности. А это дополнительная проверка после каждой операции с сокетами.
Как следствие — при использовании неблокирующих операций придётся вместо одной функции писать целый класс — машину состояний, сохраняющей точку входа. Желающие помучиться с отладкой, но писать в первом стиле могут ещё использовать нити.
При скорости передачи данных 35-40 мбайт/сек отпала необходимость в проводе.
И основных решения тут два:
1. Каждому соединению — по потоку, а то и по два (чтение и запись), используя блокирующие операции чтения и записи данных.
2. Использование select, epoll, libevent, неблокирующих операций и прочих радостей жизни.
Второй способ сильно эффективнее, но первый сильно проще в реализации, поэтому с него и нужно начинать изучение.
Кстати, Apache под Windows пользовался первым способом — создавал 100 потоков и обрабатывал каждый запрос в своём потоке.
Решения данной проблемы:
1. Создание отдельного потока для каждого клиента. Недостаток: необходимость понимания механизмов синхронизации, низкая эффективность при большом числе соединений. Новичкам будет тяжело разобраться.
2. Использование select также и для записи в сокеты. Думаю, в данном случае самое простое решение.
3. Использование более высокоуровневых языков с поддержкой асинхронного программирования.
Это не так: read() и write() эквивалентны recv() и send() с нулевыми флагами.
Ну и ещё один момент: код очень разрозненный, фрагментарный. Новичку была бы полезна ссылка на репозиторий.
Вариант с сохранением HTML и восстановлением эвентов вполне годен.
Но вместо того, чтобы облегчить страницу, ускорив её загрузку, многие выбирают второй путь: добавить ещё один фреймворк для скроллинга и хоть как-то заставить его работать.
Ради интереса проскроллил 2000 изображений в выдаче и посмотрел в DOM. Результат — в главном окне 2000 объектов с кучей потомков, одих из которых — img. И каждый раз при модификации DOM браузеру приходится рендерить страницу, учитывая это. То есть длительный скроллинг приводит к разбуханию страницы и высокой нагрузке на CPU. Самое весёлое — попробовать изменить размер страницы и смотреть, как пыжится браузер и как всё куда-то уезжает.
Я бы оптимизировал следующим образом:
1. После загрузки определённого числа изображений (например, 20-30 штук) помещал бы их в один большой прямоугольный блок, размер которого был бы фиксирован и не менялся. Блоки должны располагаться вертикально. В этом случае при изменении размера страницы тормозов будет существенно меньше, а последующие выдачи результатов будут выводиться под обновлённый размер страницы.
2. При пропадании блока из области видимости очищал бы из него вообще всё, сохраняя только минимально необходимый набор метаданных, достаточных для восстановления содержимого блока.
3. При появлении блока в области видимости восстанавливал бы его содержимое.
Вот и остаются варианты:
1. Паять датчик на коленке (с сомнительной надёжностью).
2. Ломать рабочие устройства.
3. Покупать втридорога специализированные датчики для умного дома.
При высоких значениях температуры (а 28.5 — это очень жарко) естественная циркуляция (подъём тёплого выдыхаемого воздуха вверх) ослабевает, поэтому духота нарастает быстрее. Вот кондиционер частично спасает от этого.
Ошибка и работодателей и олимпиадников заключается в том, что умения «могу разрабатывать алгоритмы для решения сложных задач» и «могу эффективно писать код» — это разные умения. Из одного не обязательно следует другое.
Лично я пошёл в науку: поначалу по инерции, потом оказалось, что это не так уж и плохо по деньгам выходит.
Как я это понимаю: организм человека является постоянным носителем многих патогенных бактерий, постоянно сдерживаемых иммунитетом. В определённых условиях иммунитет перестаёт сдерживать бактерии (ослабление иммунитета, либо внесение большого числа бактерий извне), в результате чего человек заболевает.
Применение антибиотиков позволяет помочь организму справиться с бактериальными инфекциями, путём снижения концентрации бактерий до уровня, который не представляет опасности для человека.
При недостаточном курсе болезнь недолечивается (остаётся слишком много бактерий), что чревато осложнениями. Убивается недостаточное число чувствительных бактерий, поэтому иммунитет недостаточно эффективно борется с резистетными бактериями, в итоге по завершении болезни их доля становится выше.
При нормальном курсе убивается достаточное число чувствительных бактерий, чтобы с остальными успешно справился иммунитет.
При избыточном курсе антибиотиков основной вред идёт от подавления микрофлоры кишечника и побочных эффектов. Возможно увеличение концентрации резистентных бактерий при иммунодефиците.
При применении антибиотика без показаний (заболевания) изменяется соотношение постоянно присутствующих бактерий в организме.
А раз нет юридической разницы между исследовательским и злонамеренным поиском уязвимостей, то зачем строить из себя белого и пушистого? Например, анонимно выложить уязвимость в паблик, а затем подать коллективный иск от пострадавших пациентов.
> Скажите, а такая практика в отношении публикаций в вашей области широко распространена или это лишь один из немногих примеров?
Нет, это только один пример, обычно редакторы адекватнее.
> Можно ли было опубликовать статью в журнале сопоставимого или хотя бы не сильно худшего уровня без расходов со стороны авторов?
Того же уровня — нет, без расходов — да.
> Как в итоге поступили со статьей?
Отправим в другой журнал уровнем пониже.