Перейти к основному содержимому

Эволюция разума и человечества

· 4 мин. чтения

Посмотрел несколько интересных лекций по эволюции и начал читать книгу "Сумма технологий" С. Лема. 

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

Популярные 404 ошибки

· 1 мин. чтения

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

Атаки

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

  • Wordpress - wp-login.php
  • PHPmyadmin - phpmyadmin/scripts/setup.php

Иконки для браузера

Роботам

  • robots.txt  - запреты на индексацию для поисковиков

  • crossdomain.xml - запрашивается флешем/sliverlight при кроссдоменных запросах

  • sitemap.xml - для поисковиков

  • humans.txt - авторы сайта

Дебаг JS

  • *.map файлы для дебага минимизированных js-библиотек

Ретина - *@2x.png

Для экранов с высокой плотностью пикселей некоторые сайты добавляют дублирование картинок под ios. Обычно это решается @2x суффиксом и retina.js, либо с помощью css/background-image как то описано чуть ниже. Проблема в том что файлы указывать, а иногда они проскальзывают

.icon{
width: 32px;
height: 32px;
background-image: url(icon.png);
}

@media only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-devicepixel-ratio: 1.5),
only screen and (min-resolution: 1.5dppx) {
.icon{
background-image: url(icon@2x.png);
background-size: 32px 32px;
}
}

Мониторинг 404 ошибок с google analytics

Phonegap приложение

· 5 мин. чтения

Решил тут поиграть с двумя технологиями которые прям bleeding edge нынче в IT - phonegap и angularjs. Первый позволяет абстрагироваться от родных языков для каждой платформы.. а это между прочим

  • Android - Java
  • iOS - Objective-C
  • Blackberry - Java
  • Palm OS - C, C++, Pascal
  • Symbian - C++
  • Windows C#

Всегда доступный Ubuntu desktop с X11 VNC

· 1 мин. чтения

четверг, 19 декабря 2013 г. в 14:22:34

Я уже более года обитаю в облаке Amazon EC2 и цена на него постепенно растёт, уже достигая 50$/мес. Терпение моё лопнуло и я решил переехать на digitalocean, где VM с 2 гигами RAM (для меня это основной показатель) стоит 20$. 

Стал я туда понемногу мигрировать - полный root ssh, поставил LAMP-стэк и тут вспомнил о своей мечте настроить remote desktop (X11 vnc). И тут как раз статья подходящая нашлась. Полезная штука. Под Maverics правда TigerVNC клиент устарел, но Chicken of the VNC очень даже работает.

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

Dropbox killer

Неудобнейшая штука это перетаскивание файлов. Это не VMWare, просто так файл не перетащить, но есть решение лучше.. маунтим удалённую папку! Учитывая что у меня OSX Maverics, ставим консольную sshfs:

brew install sshfs

Ставим поддержку fuxe4x для osx. Теперь маунтим удалённый рабочий стол на папку у себя на столе..

sshfs vnc@x.x.x.x:/home/vnc/Desktop Droplet

Дебаг и установка работающего Magento

· 1 мин. чтения

Небольшая заметка для себя о том как управиться с копированием и установкой на локалку существующего production-magento сайта.

  • Что-бы видеть ошибки
    cp /errors/local.xml.sample /errors/local.xml

  • Что-бы поменять настройки БД
    nano /app/etc/local.xml

  • Что-бы сменить пути идём в БД табличку core_config_data и находим по path LIKE '%base_url' ссылки. Меняем на новые.

  • Не помогло? Пути по прежнему кидают на старый сайт? Это скорей всего из-за того что Magento кеширует настройки в xml файлах. Если вы удалите кеш-файлы в var-папке..
    rm -rf var/*

    Этого может быть мало. В моём случае хардкорный дебаг Varien_Simplexml_Configкласса указал что файлы подтягиваются из временных папок.. в моём случае на маке в /var/tmp. Тоесть надо ещё
    rm -rf /var/tmp/magento/*

  • Ещё одна фишка - не ставьте localhost в качестве base_url

Радикальная честность

· 9 мин. чтения

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

Radical Honesty : How to Transform Your Life by Telling the Truth Brad Blanton 2005

За 25 лет работы психотерапевтом в Вашингтоне, я понял, что основная причина всех несчастий людей — это ложь. Я учу своих пациентов говорить правду даже тогда, когда это тяжело дается. Но зато потом они обнаруживают, что у них исчезают симптомы депрессии и тревожности, практикуя радикальную честность, они начинают чувствовать себя счастливее. У них улучшаются отношения в семье, они находят новую работу, которая им по душе.

Брэд Блэнтон

Estonian Mafia

· 2 мин. чтения

Когда-то в далёком 2008 году я писал про местные IT компании.

Если вы не следите пристально за IT и Эстонией то врядли вы заметили бы хэштег #estonianmafia упоминающийся даже президентом именно в этом контексте - бурного развития местных стартапов, многие из которых уже давно выплеснулись за пределы Эстонии просто потому что рынок тут маленький, а потенциал у производства высокий. 

Как настроить live видео вещание

· 1 мин. чтения

Уии.. мой первый видео подкаст, собственно о том как его вообще сделать. Наверняка позже я получше инструменты смогу найти, но как и в любом деле, главное начать. Мотивация с видео-играми на самом деле тут мелочь, я аналогично пытаюсь связать разные типы медиа в своём блоге и подкаст вновинку, особенно учитывая насколько я самокритичен и вижу свои недостатки с э-канием и тормозами в самовыражени. Писать проще чем быть телеведущим :)

Устройства которые я использую - Samson C03U + Canon EOS 550D. Софт - OBS + ExtraWebCam.

В трансляции я забыл упомянуть про то что twitch надо связать с программой с помощью специальных ключей (Stream Key)

Про аннотации и авторство кода

· 3 мин. чтения

Недавно опросил коллег по поводу использования @author аннотаций в коде. Большинство категорично накинулись что мол де, для этого есть VCS. Саня Мочёнов даже пристыдил что я не умею и мне лень ими пользоваться. Оокей..

Покрытие кода с PHPUnit и Selenium

· 2 мин. чтения

Расширение PHPUnit для Selenium как оказывается умеет генерировать покрытие кода! Напомню, что сам по себе Selenium через браузер бегает по сайту, тогда как покрытие кода генерируется на сервере.

Это сразу написано в документации PHPUnit, но увы это не так просто настроить. В частности нужна поддержка XDebug.

Прежде всего ставим фреймворк через composer:

{
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/phpunit-selenium": "*"
}
}

Покрытие кода тестами с jsTestDriver при использовании RequireJS

· 2 мин. чтения

Когда начинаешь писать динамический фронтэнд с backbone, постепенно выясняется что неплохо бы применять практику организации файлов как в backend. Файл разбивается на папки по типам - коллекции сюда, модели сюда, view туда. По мере разрастания этих файлов, хочется лучше видеть зависимости. 

Тут в дело включается requirejs - он навязывает определение зависимостей и обёртку кода через свою define() функцию. Можно конечно попробовать подключать файлы без этого, но я столкнулся с проблемами в iPad. Через какое-то время замечаешь удобство от наглядности зависимостей одного модуля от другого, подобно ключевому слову import в css или java.

Но с таким объявлением возникает ещё две проблемы - тормоза от числа файлов (которые по идее должны лечится объединением с помощью node + r.js или серверным ускорением с SPDY) и сложностью с юнит-тестированием.

С юнит тестами я конечно использую jsTestDriver потому что с ним просто работать в PHPStorm. Никаких Jasmine/QUnit пока не было нужно. Проблема в том что он хочет сам декларативно управлять загрузкой нужных файлов, конфликтуя с requirejs

Замена данных одного ряда таблиц Mysql

· 1 мин. чтения

(копия статьи Александра Макарова )

В MySQL есть два расширения, которые позволяют атомарно вставить или обновить запись. Годятся они для штук с довольно высокой нагрузкой, когда без блокировок не работает типичный сценарий:

Выбрать запись. Если выбралась — обновить. Если пусто — вставить.

REPLACE INTO
vote
SET
user_id = 13,
object_id = 42,
value = 7
INSERT INTO
vote
SET
user_id = 13,
object_id = 42,
value = 7
ON DUPLICATE KEY UPDATE
value = 7

 

Сходства

И то и то выражение в итоге даст примерно тот же результат. При нарушении ограничения на уникальность (то есть UNIQUE KEY или PRIMARY KEY) не будет никакой ошибки. Для ключа user_id, object_id в базе будет единственная запись с значением 7.

Отличия

Кроме очевидного отличия в синтаксисе есть и очень важно отличие в том, как всё это работает. REPLACE при срабатывании ограничения удаляет запись (и вызывает ON DELETE CASCADE) и затем вставляет новую, что не так быстро, как ON DUPLICATE KEY UPDATE, который обновляет запись без удаления.

Глубины развития персонажей

· 2 мин. чтения

Я люблю играть в RPG не только потому что они позволяют убежать в новый вымышленный мир со своей техникой и политикой, но и потому что там есть персонажи как в книгах. Некоторые из них, надолго запоминаются своим поведением. Например, ведьма Morrigan из Dragon Age. Я уж не говорю про классику художественной литературы, того же Пьера Безухова.

Работа с бинарными данными в php

· 6 мин. чтения

PHP как язык плохо подходит для работы бинарными данными напрямую. Но иногда приложения должны взаимодействовать по таким протоколам, где размер пакетов очень важен или родным форматом данных для какого-то приложения, который никем в красивый json или xml не переводится.

Целые типы данных

Напоминаю какие типы данных есть в Си, на котором основан php

ТипРазмер памятиЗначений всего
char1 байт = 8 бит256
int2 байт = 16 бит2^16=65536
short2 байта
long4 байта = 32 бита4294967295

Char при этом используется универсально согласно ASCII табличке как в качестве явного кодирования текста, так и вспомогательными маркерами. Про float я умолчу, ибо мне не понадобилось.


Нотация

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

  • Бинарная, например 0b1011

  • Восьмеричная, например 0123

  • Шестнадцатиричная, например 0xF560B1A9

Кроме этого, если вы переписываетесь с коллегами которые пишут на си, то они могут обозначать приставками или окончаниями

  • Unsigned int 14u
  • Long double или long int. Например 1.2l или 1L - фиг поймёшь, это единица или long
  • Float (с плавающей запятой) 1.3f или 1.3F

Итого, у нас char a будет хранить значение от -128 до 127.. ну или 256 если это extended ASCII. Отлично. Теперь как это использовать в php? 

Порядок битов

Честно, для меня было откровением что порядок в данных имеет значение. Я привык что 123 уже подразумевает где сотни, десятки и единицы, но для компьютера ведь всё равно. Конечно одно дело порядок написания для человека.. но тут другое - порядок записи байтов в зависимости от адреса. И больше всего удивительно что архитектуры на уровне работы с памятью разделились - x86 на стороне little endian, а за big endian SPARC и прочие. Поэтому если вы интегрируете разные архитектуры с бинарным форматом данных - договоритесь которая система будет работать.

Операции

  1. Бинарное чтение файла - fopen("binaryfile","b");

2. Битовые маски - популярный метод хранить много булевых значений в одной переменной и включать/проверять с помощью AND/OR операций. Если вы когда либо выполняли chmod 755, то уже включали эти флажки на привилий.

3. Побитовые сдвиги - помогают работать с битовыми масками и с битами в вообще

$b = $a **>>** 2; - сдвиг битов на две позиции вправо, тут может пригодится константа PHP_INT_SIZE $b = 8 >> 3; //1

4. Cyclic redundancy check

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

Вот пример самого короткого кода для CRC16 CCITT

function crc16_ССITT($data) {
$crc = 0xFFFF;
for($i = 0; $i < strlen($data); $i++) {
$x = (($crc >> 8) ^ ord($data[$i])) & 0xFF;
$x ^= $x >> 4;
$crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
}
return $crc;
}

5. Упаковка

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

Например, если вы хотите число 250 записать в один байт как char-тип, вместо того что-бы писать "строкой" в три символа, как то будет делать php по умолчанию, пишем:

pack('c', 250);

Первый аргумент это формат данных по длине. Если все данные char-типа, то можно написать c* как в регулярных выражениях, получить повторение типа. Можно написать c4, что будет аналогично cccc (четыре повторения данных char-типа)

Всего типов данных много..

  • a - строка, свободные места в поле заполняются символом с кодом 0
  • A - строка, свободные места заполняются пробелами
  • h - шестнадцатеричная строка, младшие разряды в начале (little endian)
  • H - шестнадцатеричная строка, старшие разряды в начале (big endian)
  • c - 1 байт (signed char)
  • C - 1 байт (unsigned char)
  • x - символ с нулевым кодом
  • X - возврат назад на 1 байт
  • @ - заполнение нулевым кодом до заданной абсолютной позиции 

Float

  • f - число с плавающей точкой
  • d - число двойной точности 
2 байта (целые, integer)4 байта (long)
- s - short (16 bit)- S - unsigned short- n - short (big endian)- v - unsigned short (little endian)- i - integer (размер и порядок байтов определяется архитектурой)- I - unsigned integer- l - знаковое длинное целое (32 бита, порядок знаков определяется архитектурой)- L - беззнаковое длинное целое- N - беззнаковое длинное целое (32 бита, старшие разряды в конце)- V - беззнаковое целое (32 бита, младшие разряды в конце)

Сам не проверял, но говорят что unsigned int получить не так то просто

6. Распаковка

Для раскодирования используется unpack() с аналогичным форматом типов данных, только теперь можно добавлять названия ключей для результатов ассоциативного массива
unpack("cmessageid/Vtimestamp", pack("H*",FFFF));

Заметьте что pack я тут использую вместо hex2bin, которая недоступна для версий php менее 5.4

7. Конвертирование

base_convert - конвертирование строковых представлений чисел из любого основания в другое (скажем 16 в 2)
bindec, decbin - конвертирование [2-10] двоичных и десятичных данных
octdec, decoct - конвертирование [8-10] десятичных и восьмеричных данных
hexdec, dechex - конвертирование [16-10] десятичных и шестнадцатиричных данных
ord, chr - конвертирование [256-10] десятичных и символьных (ascii) данных

base64_encode, base64_decode - конвертирование [256-256] данных, но в отличие от предыдущих форматов, данные одного значения не кодируются в 6 битах что-бы получить 64 значения, а по прежнему в 8 битах - остальные символы просто не используются.. Из-за этого формат менее эффективен в хранении, но для человека в виде текста более компактен чем нули, единицы или hex.

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

function str2bin($str, $mode=0, $visual_aid=true) {
$out = false;
for($a=0; $a < strlen($str); $a++) {
$dec = ord(substr($str,$a,1));
$bin = '';
for($i=7; $i>=0; $i--) {
if ( $dec >= pow(2, $i) ) {
$bin .= "1";
$dec -= pow(2, $i);
} else {
$bin .= "0";
}
}
/* Default-mode */
if ( $mode == 0 ) $out .= $bin;
/* Human-mode (easy to read) */
if ( $mode == 1 ) $out .= $bin . " ";
/* Array-mode (easy to use) */
if ( $mode == 2 ) $out[$a] = $bin;

if($visual_aid){
$out.=" ";
}
}
return $out;
}

function str2dec($string, $visual_aid=true){
$hex='';
for ($i=0; $i < strlen($string); $i++) {
$hex .= ord($string[$i]);
if($visual_aid){
$hex.= "(".$string[$i].") ";
}
}
return $hex;
}


function str2hex($string, $visual_aid=true){
$hex='';
for ($i=0; $i < strlen($string); $i++) {
$hex .= dechex(ord($string[$i]));
if($visual_aid){
$hex.= " ";
}
}
return $hex;
}

function hex2str($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2) {
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}

По теме советую почитать

XCOM Enemy Unknown

· 6 мин. чтения

В XCOM:Enemy Unknown, вы управляете международным центром борьбы с инопланетными захватчиками - XCOM. Этот центр на практике занимается высылкой группы из 4-6 человек на место атаки, крушения или спасения, либо следит за воздушным пространством и сбивает летающие тарелки.

Swagger

· 4 мин. чтения

Swagger UI это небольшая коллекция скриптов для создания интерактивной документации для API веб-приложений с REST протоколом. Очень полезно, если вы пишете приложение которое должно взаимодействовать с внешней системой, а договориться друг с другом в текстовом формате мало. Интерактивность проявляется в том что из документации можно делать HTTP-запросы, а сама документация зависит от комментариев в вашем коде.

Prometheus

· 5 мин. чтения

Начинается всё в возвышенном документально-Кубриковском стиле с символизмом. Мы видим нашего предка, вовсе не волосатого австралопитека, а лысого атланта-инженера-марсианина, попивающего чёрный яд у водопада с видом на улетающую тарелку. А потом видеоряд с ДНК, клетками, людьми. 

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

Дизайн интерфейсов

· 3 мин. чтения

Интерфейс подобен палке слепого - он посредник между человеком и компьютерной средой. Хороший интерфейс не мешает пользователю и позволяет сфокусироваться человеку на работе. Пользователи не единственные участники процесса разработки. Эта статья - мини конспект курса лекций на Coursera.

Dark Knight Rises

· 4 мин. чтения

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

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

Екклезиаст

· 2 мин. чтения

Давно не читал Библии, открыл почитать Екклезиаста, а до этого послушал я лекцию Кураева где он упоминал о том, что у шумеров понятие прогресса и течения времени было обратным, их язык даже говорил о том что будущее сзади (через плечо), поэтому его не видно и смотреть надо в прошлое. 

В этом свете Екклезиаст очень интересно читать. Вкратце, получив богатство и власть, увидел для себя царь фатализм, так свойственный современным циникам. Не это ли взгляд назад, на прошедшие круги? 

Все идет в одно место: все произошло из праха и все возвратится в прах.Екклезиаст 3:20

Проектирование оповещений

· 1 мин. чтения

Оповещения (notification) как правило о чём-то ( object  = существительное = событие, дружба) что изменяется ( verb  = глагол = добавлено, запрошено) кем-то ( actor  = другим пользователем, системой) и кому-то показывается (userID = пользователю, группе, компании). По сути это модель естественного языка - на этом же основаны триплеты RDF.

Вот нормализованная структура данных, хотя я использовал Mongo.

Собеседование php разработчика - темы для обсуждения

· 4 мин. чтения

Как работник, я часто ходил на собеседования и поэтому решил составить такой небольшой check-list для себя, но может пригодиться как работникам так и работодателям. Справа оставил место для заметок на случай если вы распечатаете. Отсортировано согласно логичному течению интервью

Собеседование php разработчика - темы для обсуждения

· 4 мин. чтения

Как работник, я часто ходил на собеседования и поэтому решил составить такой небольшой check-list для себя, но может пригодиться как работникам так и работодателям. Справа оставил место для заметок на случай если вы распечатаете. Отсортировано согласно логичному течению интервью

Профилирование PHP проектов

· 5 мин. чтения

Профилирование это анализ потребления ресурсов при работе программы. Этимология слова видимо связана с тем что профиль это некая граница, отсюда - поиск границ компонентов ПО в ресурсном пространстве. В моём случае программа это исполняемые php-скрипты, а ресурсы это время, память и нагрузка на процессор. Время исполнения не всегда связано с нагрузкой процессора. Процесс может ждать IO-ответа от более медленных источников, а может и просто спать.

Я писал про микрооптимизацию в php. Как правило отмечали критики, в общем случае она не нужна. Профилирование это взгляд с высоты птичьего полёта на подключаемый код. Он делается только на рабочей машинке, а не на production. В некоторых LAMP-сборках инструменты для этого уже установлены.

XDebug

XDebug - это php модуль, я уже давно с ним работаю как с дебаггером.

zend_extension = xdebug.so
xdebug.profiler_enable = 1
xdebug.profiler_aggregate = On
xdebug.profiler_output_dir = /tmp

Он позволяет генерировать доклад о профилировании в форме файла. Из-за глубокой иерархичности, доклад обычно весит несколько мегабайт. Настройки модуля хранятся в php.ini, там же можно и указать путь к результату профилирования. Назовём его cachegrind.out - он совместим с более общим форматом valgrind

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

  1. PHPStorm (Tools - Analyze stacktrace)

  2. webgrind

  3. WinCacheGrind

  4. KCacheGrind 

XHProf

Screen Shot 2012-07-06 at 11.31.19.png

XHProf - пакет PECL, написан в Facebook, поставляется тоже как модуль (xhprof.so или xhprof.dll). Позволяет учитывать значительно больше параметров, в т.ч. нагрузку на CPU и оперативную память. Позволяет сравнивать повторные запуски и агрегировать их результаты. Наиболее полезная фича - суммарный анализ по времени в виде весового графа. Граф генерируется с помощью graphviz и утилитки dot. У меня были небольшие проблемы под маком, пришлось поставить вручную.

pecl install xhprof-0.9.2

Редактируем php.ini:

 extension=xhprof.so
xhprof.output_dir=/var/tmp/xhprof

Поскольку просмотр результатов xhprof целиком web-based, то надо залинковать где-то в корне htdocs путь к xhprof_html папке. Для подключения, необходимо изменять свои скрипты. Т.е. где-то в начале своего index.php ставится include, инициализация и что-бы не бояться за какой-то exit, хук на register_shutdown_function. Вместо того что-бы инклудить каждый раз, можно воспользоваться php-директивой auto_prepend_file и включать это файл всегда

//результат будет виден с ?xhprof=1
if (extension_loaded('xhprof') && $_GET['xhprof']) {
include_once 'xhprof_lib/utils/xhprof_lib.php';
include_once 'xhprof_lib/utils/xhprof_runs.php';
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

function end_xhprof(){
$profiler_namespace = 'myapp'; // namespace вашего приложения
$xhprof_data = xhprof_disable();
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace);

//Замените относительный путь к залинкованной папке
$profiler_url = sprintf('http://' . $_SERVER['SERVER_NAME'] . '/xhprof/index.php?run=%s&source=%s', $run_id, $profiler_namespace);

echo 'XHProfiler output';
}

register_shutdown_function('end_xhprof');
}

Можно конечно не делать echo ссылки, а прятать это в javascript-консольку для firebug'а, более подробно советую почитать статью Игоря Бровченко, он даже сравнивал несколько php-фреймворков.. или Лорензо Албертона

Слежка

Профайлеры конечно хороши когда есть начало, конец и результат в виде доклада. Но когда php висит как демон очень долго и хочется понять где же это он тормозит.. В утилитках типа phpcs для вывода деталей работы, часто существует флаг -v (verbose mode). Но до того как я это узнал, мой процесс уже час как висел в jenkins'е и я незнал, стоит ли мне убивать его, или он что-то полезное таки делает. К счастью, в общем случае, можно следить за IO-действиями любого процесса без его согласия с помощью strace:

strace -p IDпроцесса strace php index.php #запустит трейс вместе за запуском php в CLI режиме 

Дебаг зависимостей

PHPStorm умеет искать использование методов и классов, но это статический анализ, а вот для того что-бы динамически построить дерево зависимостей, есть отличный pecl модуль inclued (на момент установки у меня - 0.1.3)

pecl install inclued

Теперь так же редактируем php.ini:

extension=inclued.so
inclued.enabled=1
inclued.dumpdir=/tmp/inclued

Это нам даёт при каждом запросе файл с сериализованным выводом функции inclued_get_data(), которая возвращает все подключённые файлы.

Если следовать мануалу, то по идее так можно сгенерировать png-файлик..

php /usr/lib/php/pear/gengraph.php -i inclued.06567.1
dot -Tpng -o inclued.png inclued.out.dot

..но у меня это просто белый квадратик. Я попробовал другой gengraph.php из репозитория Йориса Бертелота

git clone https://github.com/eexit/Inclued.git /Users/artjom/PhpstormProjects/inclued/ 
sudo php /Users/artjom/PhpstormProjects/inclued/Inclued/gengraph.php -i inclued.07576.1
dot -Tpng -o inclued.png inclued.out.dot
open inclued.png

Увы он оказался малость битым, работал только режим зависимости классов, а не файлов, к тому же только в горизонтальном виде. Пришлось немного попатчить, в частности у dot есть режим rankdir = "LR"; с помощью которого сгенерилась красота на 6 мб.. ужас что так много инклудится, но красиво что так это обнаруживается. 

Это кстати результат загрузки админ-странички у opensource CRM'ки zurmo-stable-0.6.90, в основном там не столько Yii сложен, сколько незамороженный Readbean..

Как оказалось чуть позже, граф зависимостей файлов (режим php gengraph.php -T includes) не работал из-за конфликта с XDebug.

Gephi

Если вам как и мне не нравится что XHProf и Inclued полагаются на graphviz и dot для визуализации, то можно воспользоваться более интересным инструментом - Gephi. Тут надо смотреть как вы хотите это анализировать - можно брать наполовину собираемый .dot файл и импортировать его, а поскольку Gephi не умеет кушать json, то как вариант - парсить исходные данные и генерировать что-то типа CSV

Inclued уже сам генерирует inclued.out.dot в указанной папке, поэтому можно использовать его сразу. На выходе имеем..

Для того что-бы нарисовать картинку XHProf, надо чуть изменить файл callgraph_utils.php, в частности функцию xhprof_get_content_by_run. Она передаёт сгенерированный dot-скрипт напрямую в dot утилиту для генерации картинки. Поэтому просто сохраним его на диск для Gephi.. 

$dotfile = '/tmp/'.time().'.dot';
touch($dotfile);
$fp = fopen($dotfile,'w+');
fwrite($fp,$script);
fclose($fp);

С этим несколько проблем. Первая - это полуфабрикат - данные для dot уже агрегированные, есть только label, куда засунули и время, название метода, число вызовов, проценты и тп. Вторая - файл генерируется только когда открыть генерацию графа в png-формате в браузере

Tribes ascend

· 5 мин. чтения

Tribes: Ascend это бесплатная сетевая стрелялка от HiRez studios на движке от Unreal с моделью платной прокачки, подобно World of Tanks и League of Legends. В большинстве режимов игры участвуют две группы бойцов по 16 игроков в каждой (т.н. Blood Eagle и Diamond Sword) на одной из ~10 карт

Анализ сетей

· 6 мин. чтения

Графы это математическая формализация сетей. Поскольку я до дипломной работы перерыл много материалов, то тут буду собирать интересные доклады по этой общей теме. Эта статья составлена на основе курсов лекций Networked Life (Michael Kearns, Pennsylvania) и Social Network Analysis (Lada Adamic, Michigan) в Coursera.

Интереснейшие проблемы анализа сетей это поиск кратчайшего путивизуализация и заражение

Терминология

Наука изучения сетей междисциплинарная, поэтому и термины могут применяться разные.

ТочкиЛинииОбласть применения
Vertices (вершины)Edges, arcs (рёбра)Математика
Nodes (узлы)Links (связи)Инфотехнологии
SitesBondsФизика
ActorsTies, relationsСоциология

Программные инструменты 

GephiNetlogoiGraphPajekUCINetNodeXLNetworkXSoNIA.

Компоненты

В зависимости от того, как моделируется сеть (направленно или нет), зависят и некоторые её характеристики. Можно говорить о сильно связанном компоненте направленной сети, если из каждой его вершины можно попасть в любую другую. Большие естественные сети рано или поздно образуют гигантский компонент

Особенности естественных сетей

Кратчайший путь определяется только если сеть не имеет изолированных узлов (disconnected component). Проблема выражается в ограниченности видимости конкретного узла. Так, в социальных сетях человек ограничен знанием о своём окружении, поэтому он не видит всей картины, связывающей его с произвольным узлом остальной сети (small world effect).

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

Естественные сети (в отличие от скажем случайных сетей),  стремятся к минимизации кратчайшего пути и по мере роста числа узлов, среднее кратчайшее расстояние (диаметра сети) асимптотически уменьшается. Социальные сети на основе эмпирических исследований Траверса и Милграма (1969 г.), Лешковеца и Горвица (2008 г.) и Бэкстрома и др. (2012 г.) показывает что значение диаметра в районе 5.

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

Наконец третье свойство - длинный хвост в распределении степеней вершин (heavy tailed degree distribution, степенной закон, принцип Парето 20/80). Это проявляется в том, что в обществе есть редкие вершины, число связей у которых очень велико, а в среднем по сети "популярность" падает довольно резко и нелинейно

Заражение (перколяция, диффузия) в сетях может происходить необычайно быстро из-за пограничного свойства как структуры сети, так и свойств заражения (tipping point, threshold). Если взять случайно сгенерированный граф у которого средняя степень узла равна 4, то легко увидеть что при 100% степени заражения, порядка 90% узлов будет покрыто.

\[e=d*N/2\]

e - число рёбер
d - средняя степень узла
N - число узлов в сети

Число рёбер для ненаправленного графа

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

Скопления

Для любой вершины можно определить степень скопления (clustering coefficient) как показатель взаимосвязанности её соседей. Если все вершины связаны, то такой подграф называется клик (clique) и имеет коэффицент 1. Теперь для расчёта коэффициента среднего скопления, достаточно просчитать коэффициент для всех вершин и взять среднее значение

\[C(u) = \frac{k+m}{k(k-1) /2 }\]

C(u) - коэффициент кластеризации вершины u
k - степень вершины
m - число связей "между друзьями"

Коэффициент кластеризации вершины

Коэффициент кластеризации имеет смысл сравнивать не просто с нулём, а со средней плотностью рёбер в графе, которая одновременно является и вероятностью что две вершины имеют общую связь

\[p = \frac{E}{N(N-1)/2}\]

p - плотность рёбер в графе
E - число рёбер в графе
N - число вершин

Плотность рёбер

Для естественных сетей C(u) значительно больше p

Моделирование скоплений

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

\[y \sim p + (\frac{x}{N})^a\]

y - вероятность создания новой связи между двумя вершинами
p - вероятность случайной связи
x - число общих друзей между вершинами
N - размер всей сети

alpha-модель

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

Предпочтительное связывание

Описанные модели формирование скоплений тем не менее не объясняют почему распределение степеней вершин подчиняется степенному закону. 

\[p(k) = Сk^{-\alpha}\]

p(k) - вероятность вершины иметь степень k
α, C - константы

Распределение со степенным законом

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

Навигация

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

Модель Клейнберга предполагает что сеть упорядочена в матрицу k на k и каждая вершина знает свои координаты. Передача сообщения в таком случае сводится к выбору соседней вершины, наиболее близкой географически к глобальной цели. При этом можно ввести сопротивление в движении 

\[p(d) \propto (1/d)^r\]

p - вероятность новой связи между двумя вершинами
d - расстояние между вершинами
r>=0 - степень, влияющая на поведение

При очень больших r, передача сообщений происходит только локально и кратчайшие расстояния до дальних вершин могут даже не существовать.

Приуменьшении r, падает сопротивление от расстояния, но увеличивается алгоритмическая сложность поиска кратчайшего расстояния

Важные вершины

До этого всё что касалось характеристик, описывало всю сеть целиком, но единичные вершины также критично важны.

Pagerank

Один из способов оценки важности вершин в направленном графе основывается на пошаговом рекурсивном алгоритме вычисления важности вершины основываясь на важности ссылающихся на эту вершину входящих рёбрах-ссылках (out-degree). В случае если эти величины у всех вершин остаются неизменными и граф не меняется, то можно считать что сеть достигла равновесия.

\[R(p) = \sum_{q \in POINTS(p)} \frac {R(q)}{out(q)}\]

R(p) - pagerank вершины p
R(q) - pagerank вершины q которая ссылается на p (принадлежит множеству POINTS)
out(q) - число исходящих ссылок из q

page rank

Вот например как выглядит расчёт для некоторых вершин..

Рациональные процессы в сетях

Модель сегрегации Шеллинга

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

См. эмулятор.

Начальное случайное положение

Сегрегация при 40 процентах требований достигает 80 процентов похожести

Drupal 7

· 4 мин. чтения

среда, 8 августа 2012 г. в 07:20:52

Drupal 7 это конструктор сайтов (CMF). А это - его краткий обзор на основе того малого опыта что у меня был (так что это скорей статья для меня самого). Седьмая версия уже устарела, скоро готовится выйти 8 версия, частично перенявшая symfony framework

Если обобщить

Основное отличие от CMS - то что схему данных пользователь добавляет сам. Фактически вместо одной таблички БД, часто используется несколько таблиц под каждое поле что с одной стороны даёт гибкие возможности пользователю на лету создавать динамические наборы объектов, давать привилегии на него или его свойства, делать многоязычность и многоверсионность.

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

PHP-процессы при загрузке страниц довольно далеки от оптимального и могут занимать 50-70 мб, что вынуждает активно оптимизировать сайты с кешированием на Varnish и Memcache, перекидыванием поиска на Solr, включением opcode кэширования, Nginx и тп.

Теоретически Drupal поддерживает другие БД типа Mongo, но практически многие модули заточены под MySQL.

В плане frontend всё неплохо - "drupal frontend developer" может работать без хорошего IDE, потому что php-шаблоны генерируются из админки со своими названиями и префиксами в зависимости от типа блоков. Поэтому и возникают  компании, как то из местных - okiamekaiafenomen, банально легко интегрировать дизайн, когда схема тоже сделана в UI.

Терминология

Вот термины которыми оперирует система и стандартный сайт

  1. Content/Entity type концептуально это аналог классов - у них тоже есть свойства (Fields + Properties)

  2. Entities - собственно instance классов

  3. Nodes (+ Article, Users, Comments, Tags) - тоже по сути Entities, экземпляры классов

  4. Views, Regions, Panels. Динамические (могут вызывать методы)

  5. Menus - древовидная структура меню. Элементы могут быть привязаны к странице и её частям. Доступ по URL могут

  6. Modules. Собственно функционал.

  7. Themes. Аналогично модулям, только для стилей (CSS)

Структура админки

  • Content - редактирование статей и прочего содержания клиентом
  • Structure - порядок размещения блоков, изменение типов данных

Структура БД и пример запроса

Центральное место - табличка node, на которой и завязано всё содержимое. Пример запроса..

db_query("SELECT * FROM node LIMIT 5")->fetchField();
fetchObject();

Качество кода

Код - необъектное говно. Нет классов, интерфейсов, пространства имён. Сплошь и рядом используются глобальные переменные, поэтому юнит тестами покрыть его нельзя. Модули состоят из набора обычных функций со своеобразной практикой наименования, например приватные функции имеют _ префикс.  Впрочем, если сравнивать с Joomla, то архитектура более предсказуемая.

Хуки (специально названные функции) меняют данные на лету, если существует функция c похожим именем, проходя по всем модулям. Отсюда и тормоза и гейзенбаги. Например предлагая hook_foo_bar будет вызван baz_foo_bar в модуле baz. 

Есть свой формат для кода, но он не PSR, использует пробелы вместо табов. PHPStorm можно настроить с правилами Code_Sniffer скачав из модуля.

Drush

Drush это консольная утилита, облегчающая рутину, в частности очистку кэша. 

 

Ставится просто, но нуждается в связи с локальным mysql

pear channel-discover pear.drush.org 
sudo pear install drush/drush
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock

 

Теперь, находясь в папке проекта можно быстро ставить модули и чистить кэш

drush dl module_name 
drush en module_name
drush cc all

 

Модули

У каждого своя папка с файлами .info и .module. По важности выделяются четыре типа, код лежит в разных местах

  1. core, optional core (/modules)

  2. contrib modules (sites/all/modules),

  3. custom modules (sites/default/modules) + VCS symlink 

Важные модули

- Views- Rules - для ограничений (форм)- Pathauto & token - для ЧПУ- Devel - для дебага- Wysiwyg / inline images- Context- Flags- Entity API- Menu Block- Menu Breadrumb  - Module filter- Chart APi- Features- Feeds- Custom formatters- SmartCrop- File Entity- IMCE- Media - CAPTCHA- OAuth- Entity tokens- Image crop- Job scheduler- Multiblock- Pathauto- Token- Google analytics- Webform- Chaos tools

Дистрибутивы

Почитать

Taxist

· 3 мин. чтения

воскресенье, 29 апреля 2012 г. в 18:13:43

Начал составлять свой рейтинг фильмов на flickchart и естественным образом столкнулся с новыми фильмами, в том числе классикой, которую ещё не видел.

"Таксист" с Робертом Де Ниро 1976 года один из них. Отличный нуар-фильм Мартина Скорсезе и мне как интроверту, любящему копаться в себе и критиковать других очень интересен. Главный герой, Трэвис - одинок и потерян. У него бессонница, депрессия и паранойя. 

Iron Lady

· 2 мин. чтения

среда, 11 апреля 2012 г. в 21:06:01

Очень тронул фильм про Маргарет Тетчер. Он не простой и не для развлечения. Он путеводный, подобно словам произносимым в первой части фильма:

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

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