Pull to refresh
41
0
Dmitriy T. @zibada

User

Send message
Я был бы безумно счастлив согласиться с автором, но увы, практика показывает ровно обратное.

Про веб вообще лучше промолчу, да и здесь все уже написали:
https://habrahabr.ru/post/278655/

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

Недавно был вынужден перейти со связки Miranda+Gmail на Telegram. У последнего нашлось ровно два клиента под десктоп:
  • Официальный, который официально не умеет (и официально не хочет уметь) киллер-фичу телеграма — секретные чаты. Поиска по истории нет вообще, точнее, он не работает, понадобилось найти сообщение годичной давности — извольте мотать бесконечный скролл до посинения пальцев.
    (неужели такая проблема в 2016 году хранить пару мегабайт текста и искать по нему локально?)
  • Cutegram, про который достаточно знать то, что он весит несколько сотен (!) мегабайт и при установке распаковывает несколько десятков тысяч мелких файлов с картинками (я представляю, каково здесь обладателям HDD). При этом, кроме чатов, умеет он не сильно больше официального.

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

Короче, я очень надеюсь, что спрос на компактные и быстрые решения снова будет расти, работы здесь — непаханое поле.
Смена имени при смене содержимого сломать ничего не должна.
Если браузер префетчит css версии 2477, заходит на страницу, а у нее в head — уже версия 2478, очевидно, что префетченную версию надо выкинуть (точнее, окажется, что это будет случайный документ, никак не связанный с текущей страницей) и скачать актуальный стиль.
Проблемы могут возникнуть как раз при простой перезаписи файла и отсутствии правильных настроек кэша.
Я не знаю, в какой области вы специалист, но ваш комментарий и по стилю, и по содержанию больше напоминает рассуждение деревенской бабки на завалинке.
К сожалению, у российских депутатов уровень владения темой и логикой примерно такой же.

1. «Биткоинты», ага.
2. «Китаезы», значит, запретили? Это у которых весь последний год проводится ~85-90% всего мирового объема торгов? Ну-ну.
3. Этот самый весь мировой объем со сравнению хотя бы с тем же форексом — это такая пыль, что сейчас вряд ли стоит всерьез обсуждать какое-либо влияние на мировую и уж тем более российскую экономику.
4. Биткоины от запрета волшебным образом существовать не перестанут, и вряд ли нарушение еще одного идиотского закона станет проблемой для злоумышленников, проблемы, как всегда, возникнут только у честных пользователей.

Зачем на верхнем уровне все запихивать в один array?
Общепринятный формат вывода многих юниксовых утилит — «одна строка — один объект».
Его и стоит придерживаться, только формат отдельных строк сделать json вместо каши из произвольных разделителей.
То есть, выводить список объектов по одному на строке, разделять \n, заканчивать EOF, \n в значениях полей эскейпить.

Бонусы:
1. Итерация по строкам тривиально реализуется во всех языках программирования, без специальных json-парсеров
2. Стандартные head, tail, uniq и прочие работают из коробки как надо, даже не зная, что в строках json
3. Человекочитаемо даже без специального pretty-print
4. Это никак не ограничивает возможность создания вложенных списков или принудительного представления вывода одним array, если ну очень хочется.
Как я понял из чтения документации и тикетов:

В OpenVZ существуют две разных модели ограничения памяти:

1. User Beancounters
2. Более новая VSwap

Монга сама никак не контролирует расход памяти, а сваливает эту задачу на ядро (используя mmap-ы на файлах).
Если свободной физической памяти много, ядро спокойно ее использует как кэш, ему не жалко.
Проблема в том, что OpenVZ в режиме UBC считает всю эту память в лимит контейнера.
Как это проявляется: если в монгу долго писать, она ест все больше и больше памяти, в какой-то момент времени лимит превышается, затем либо процесс монги убивается OOM, либо сыпятся ошибки выделения памяти в других процессах.

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

Персональные каналы я бы делал так:
— id канала — это хэш наподобие session id, можно даже его и использовать, модуль умеет читать id канала из кук
— каждый клиент подписывается одновременно на два канала — общий и свой персональный, модуль это опять же умеет делать в рамках одного соединения.
— если сессия стала невалидна — убиваем канал с сервера

Безопасность получается на том же уровне, что и остального приложения (угон id канала равносилен угону сессии), если надо — завернули все в https средствами того же nginx.
Я разве где-то упомянул php?
Можно, на самом деле, и обычный xhr post засовывать в ту же очередь вместо fastcgi, и затем чем прицепились к очереди, тем и читаем, хоть bash-скриптом.
Хотя, по-моему, чтобы не плодить сущности, удобнее это делать на том же языке, на котором написана остальная логика.
Раз уж не надо самому возиться с многопоточностью (эта работа взвалена на откомпилированный сишный модуль), почему бы и нет.
Если воркер все же нужен многопоточный, то непонятно, чем плох fastcgi, который все равно уже есть.
Думаю для одного небольшого проекта попробовать вот такую штуку:
github.com/wandenberg/nginx-push-stream-module

Бонусы:
— вся мощь nginx в обработке асинхронных запросов
— поддерживает несколько способов раздачи одновременно — polling, long-polling, eventsource, websockets
— в комплекте есть js-библиотека, реализующая их все и умеющая graceful degradation, но можно и самому все сделать.
— можно использовать как простенький сервер очередей
— включен в пакет nginx на dotdeb, то есть ставится без свистоплясок одной командой или уже есть

Идея в том, чтобы всю раздачу сообщений пользователям свалить на полностью готовое решение, а существующий бэкэнд сделать максимально тупым, чтобы он только постил апдейты в канал.
Отпадает необходимость городить отдельный сервер на node.js+redis и подобном.

Обратный канал оставить на классическом xhr+fastcgi, он все равно нужен, если делать graceful degradation.

Теоретически модуль умеет принимать publish в канал с клиентов, подключившихся через вебсокеты, но реализовано это как-то коряво (publish делается в тот же канал, на который была подписка).
Если очень надо, можно, наверное, открыть второе websocket-соединение на отдельный канал чисто на отправку, хоть это и костыль.
Тогда можно и fastcgi выкинуть совсем, читать сервером сообщения, прицепившись локально к nginx через обычный http streaming к этому каналу.
location ~ /\. {
	deny all;
}

и именую все «скрытые» директории с точки, как это принято в *nix
одновременно решается проблема со служебными директориями систем контроля версий.
Это классическая ошибка незнакомых с теорией вероятностей.
Перемножать вероятности можно только для независимых событий.
Если причиной выхода из строя является какое-нибудь сильно неблагоприятное сочетание внешних условий, и вероятность их наступления 0.1%, то вероятность выхода из строя двух компов одновременно… примерно те же 0.1%.

Насколько я помню, основной версией фейла фобос-грунта является как раз одновременный выход из строя обоих компов по причине одной весьма неудачно пролетевшей заряженной частицы.
Добавлю:
в пакетах libapache2-mod-php5 и mime-support для Debian (возможно, и для Ubuntu) по умолчанию используется потенциально небезопасная конфигурация.

В /etc/mime.types для application/x-httpd-php прописаны расширения .php .phtml .pht (!!!)
При этом в /etc/apache2/mods-available/php5.conf есть строчка
<FilesMatch "\.ph(p3?|tml)$">

беда которой в том, что она создает чувство ложной защищенности, т.к. с такими mime.types все работает и без нее.
И, вероятно, не совсем так, как вы ожидаете — как насчет файла с замечательным именем «hello.pht.en»?

Эта «черная магия» отключается дописыванием строки
RemoveType .php .pht .phtml .php3 .php4 .php5

все в тот же php5.conf.

На всякий случай:
текущие результаты еще не окончательные!

Рановато кого-либо поздравлять.
Не.
С пустым array() будет
<li></li>
а давайте просто достанем и померяемся

тестирующий, не побоюсь этого слова, фреймворк (PHP 5.4.0 with Xdebug v2.2.0rc1):
$arr = range(0, 100500);
$start = xdebug_time_index();
// code...
echo xdebug_time_index() - $start . ' ' . memory_get_peak_usage();


результаты:
for ($i = 0; $i < floor(count($arr)/2); $i++)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[count($arr)-$i-1];
    $arr[count($arr)-$i-1] = $tmp;
}

0.63774108886719 8691144

$rev = array();
while ( count( $arr ) ) $rev[] = array_pop( $arr );

0.60788989067078 9214832

$count = count($arr);
for ($i = 0; $i < floor($count/2); $i++)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[$count-$i-1];
    $arr[$count-$i-1] = $tmp;
}

0.19419097900391 8691048

$count = count($arr);
for ($i = intval($count / 2) - 1; $i >= 0; $i--)
{
    $tmp = $arr[$i];
    $arr[$i] = $arr[$count-$i-1];
    $arr[$count-$i-1] = $tmp;
}

0.041511058807373 8691048

$pieces = count($arr)-1;
$reversed = array();
while($pieces >= 0) {
    $reversed[] = $arr[$pieces--];
}

0.039575099945068 14038952

for ($l = 0, $r = count($arr) - 1; $l < $r; ++$l, --$r)
{
    $t = $arr[$l]; $arr[$l] = $arr[$r]; $arr[$r] = $t;
}

0.03570294380188 8690680

$arr = array_reverse($arr);

0.014595031738281 14038056
чем-то напоминает всем надоевшую картинку:

ситуация: есть 15 плохо работающих копирастских законов
— а давайте наконец наведем порядок и примем такой закон, чтобы уж точно победить пиратство раз и навсегда!

ситуация: есть 16 плохо работающих копирастских законов
Но это же не «дублирующийся функционал», а совершенно разные вещи — байтовая строка и символьная строка.
Два набора функций — это хоть и зло, но едва ли не наименьшее из возможных.

Исторически получилось, что в php были только байтовые строки, и нельзя делать вид, что их больше нет, потому что это моментально ломает любой существующий код, работающий с бинарными файлами или сетевыми протоколами, да и вообще с любыми данными не в utf-8.
Поэтому нельзя просто так взять и «перейти на юникод» одним волшебным патчем — поди разбери, где в старом коде вызов какого-нибудь substr() должен на самом деле работать с байтами, а где с символами.
По этой же причине всякие mbstring.func_overload являются мертворожденными костылями.

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

Итого:
проблема есть, простого решения она не имеет, выбранное решение, к сожалению, больше создает новых проблем, чем решает старых.
Потом все будут жаловаться, а что это хостинги не спешат переходить на новую версию — ну а какому хостеру в здравом уме надо, чтобы при апгрейде у него сломались абсолютно все сайты, использующие кодировку, отличную от utf-8.
Довод всего лишь в том, что никаких «массивов изменений» в природе не существует, есть две независимые друг от друга копии структуры со ссылками на одни и те же значения.
Ничего по завершению цикла никуда само не применяется, тот массив, по которому бежит foreach, и переменная, доступная по имени $a — это две разные переменные, и первая из них по завершению цикла просто выбрасывается.
Ссылку можете добавить, но и по тем ссылкам, что уже приведены, написано примерно то же самое :)
> Получается, что в последней итерации цикла foreach в данном случае потребление массивом памяти возросло в два раза, хотя по самому коду это не очевидно. Но сразу после цикла, потребление памяти вернулось к прежнему значению. Чудеса да и только.
> Причиной тому является оптимизация использования массива в цикле. На время работы цикла, при попытке изменить исходный массив, неявно создается «массив изменений исходного массива» (не копия), который «применяется» к исходному массиву сразу по завершению цикла.

Здесь написана какая-то хрень.
foreach($a as $k => $v) исходный массив копирует полностью при первом изменении (то же самое происходит при любой передаче «по значению» в функцию).
Чтобы этого не было, надо писать foreach($a as $k => &$v)

Но! Копирование массива в php не приводит к deep copy всех его значений, копируется (и дальше изменяется) только его хэш таблица.
Получаем два независимых массива, у которых, тем не менее, память под одинаковые элементы выделяется один раз.
Поэтому overhead от копирования зависит от того, что считать «большим» массивом.
Если это массив из пяти элементов пусть даже по мегабайту каждый, копирование будет почти бесплатным.
Если же это массив вида range(0, 100500), то есть из большого числа мелких элементов, то его копия сожрет куда больше памяти.

proof:
<?php

echo memory_get_usage() . "\n";
$a = range(0, 100500);
echo memory_get_usage() . "\n";

foreach ($a as $k => $v)
{
	if ($k == 0 || $k == 1 || $k == 100500) echo memory_get_usage() . "\n";
	$a[$k] = 1;
}


Видно, что на первой итерации цикла копий вообще никаких нет (пока массив мы не меняем), на второй итерации создается полная копия массива $a (foreach продолжает бегать по старой копии) и это съедает сразу много памяти, дальше до конца память постепенно выделяется на zval-ы отдельных заменяемых элементов.
Если заменить последнюю строку на $a[$k] = $a[$k], увидим, что выделения памяти на новые zval больше не будет, но копия массива один раз все равно создастся.

Еще раз размещу ссылку на вот эту замечательную статью, там эти вопросы довольно неплохо разжеваны.

Information

Rating
Does not participate
Registered
Activity