Всегда доступный Ubuntu desktop с X11 VNC
четверг, 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
Небольшая заметка для себя о том как управиться с копированием и установкой на локалку существующего 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
Радикальная честность
Я начал практиковать радикальную честность чуть более года назад. Начал читать книгу и сразу понял что есть тут какой-то бред. Тем не менее, два брака спустя, я по-прежнему считаю что сознательно быть честным, было важнейшим решением.
Radical Honesty : How to Transform Your Life by Telling the Truth Brad Blanton 2005
За 25 лет работы психотерапевтом в Вашингтоне, я понял, что основная причина всех несчастий людей — это ложь. Я учу своих пациентов говорить правду даже тогда, когда это тяжело дается. Но зато потом они обнаруживают, что у них исчезают симптомы депрессии и тревожности, практикуя радикальную честность, они начинают чувствовать себя счастливее. У них улучшаются отношения в семье, они находят новую работу, которая им по душе.
Брэд Блэнтон
Estonian Mafia
Когда-то в далёком 2008 году я писал про местные IT компании.
Если вы не следите пристально за IT и Эстонией то врядли вы заметили бы хэштег #estonianmafia упоминающийся даже президентом именно в этом контексте - бурного развития местных стартапов, многие из которых уже давно выплеснулись за пределы Эстонии просто потому что рынок тут маленький, а потенциал у производства высокий.
Как настроить live видео вещание
Уии.. мой первый видео подкаст, собственно о том как его вообще сделать. Наверняка позже я получше инструменты смогу найти, но как и в любом деле, главное начать. Мотивация с видео-играми на самом деле тут мелочь, я аналогично пытаюсь связать разные типы медиа в своём блоге и подкаст вновинку, особенно учитывая насколько я самокритичен и вижу свои недостатки с э-канием и тормозами в самовыражени. Писать проще чем быть телеведущим :)
Устройства которые я использую - Samson C03U + Canon EOS 550D. Софт - OBS + ExtraWebCam.
В трансляции я забыл упомянуть про то что twitch надо связать с программой с помощью специальных ключей (Stream Key)
Про аннотации и авторство кода
Недавно опросил коллег по поводу использования @author аннотаций в коде. Большинство категорично накинулись что мол де, для этого есть VCS. Саня Мочёнов даже пристыдил что я не умею и мне лень ими пользоваться. Оокей..
Покрытие кода с PHPUnit и Selenium
Расширение PHPUnit для Selenium как оказывается умеет генерировать покрытие кода! Напомню, что сам по себе Selenium через браузер бегает по сайту, тогда как покрытие кода генерируется на с ервере.
Это сразу написано в документации PHPUnit, но увы это не так просто настроить. В частности нужна поддержка XDebug.
Прежде всего ставим фреймворк через composer:
{
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/phpunit-selenium": "*"
}
}
Покрытие кода тестами с jsTestDriver при использовании RequireJS
Когда начинаешь писать динамический фронтэнд с backbone, постепенно выясняется что неплохо бы применять практику организации файлов как в backend. Файл разбивается на папки по типам - коллекции сюда, модели сюда, view туда. По мере разрастания этих файлов, хочется лучше видеть зависимости.
Тут в дело включается requirejs - он навязывает определение зависимостей и обёртку кода через свою define() функцию. Можно конечно попробовать подключать файлы без этого, но я столкнулся с проблемами в iPad. Через какое-то время замечаешь удобство от наглядности зависимостей одного модуля от другого, подобно ключевому слову import в css или java.
Но с таким объявлением возникает ещё две проблемы - тормоза от числа файлов (которые по идее должны лечится объединением с помощью node + r.js или серверным ускорением с SPDY) и сложностью с юнит-тестированием.
С юнит тестами я конечно использую jsTestDriver потому что с ним просто работать в PHPStorm. Никаких Jasmine/QUnit пока не было нужно. Проблема в том что он хочет сам декларативно управлять загрузкой нужных файлов, конфликтуя с requirejs
Замена данных одного ряда таблиц Mysql
(копия статьи Александра Макарова )
В 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, который обновляет запись без удаления.
Глубины развития персонажей
Я люблю играть в RPG не только потому что они позволяют убежать в новый вымышленный мир со своей техникой и политикой, но и потому что там есть персонажи как в книгах. Некоторые из них, надолго запоминаются своим поведением. Например, ведьма Morrigan из Dragon Age. Я уж не говорю про классику художественной литературы, того же Пьера Безухова.
Работа с бинарными данными в php
PHP как язык плохо подходит для работы бинарными данными напрямую. Но иногда приложения должны взаимодействовать по таким протоколам, где размер пакетов очень важен или родным форматом данных для какого-то приложения, который никем в красивый json или xml не переводится.
Целые типы данных
Напоминаю какие типы данных есть в Си, на котором основан php
Тип | Размер памяти | Значений всего |
char | 1 байт = 8 бит | 256 |
int | 2 байт = 16 бит | 2^16=65536 |
short | 2 байта | |
long | 4 байта = 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 и прочие. Поэтому если вы интегрируете разные архитектуры с бинарным форматом данных - договоритесь которая система будет работать.
Операции
- Бинарное чтение файла - 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
В XCOM:Enemy Unknown, вы управляете международным центром борьбы с инопланетными захватчиками - XCOM. Этот центр на практике занимается высылкой группы из 4-6 человек на место атаки, крушения или спасения, либо следит за воздушным пространством и сбивает летающие тарелки.
Swagger
Swagger UI это небольшая коллекция скриптов для создания интерактивной документации для API веб-приложений с REST протоколом. Очень полезно, если вы пишете приложение которое должно взаимодействовать с внешней системой, а договориться друг с другом в текстовом формате мало. Интерактивность проявляется в том что из документации можно делать HTTP-запросы, а сама документация зависит от комментариев в вашем коде.
Prometheus
Начинается всё в возвышенном документально-Кубриковском стиле с символизмом. Мы видим нашего предка, вовсе не волосатого австралопитека, а лысого атланта-инженера-марсианина, попивающего чёрный яд у водопада с видом на улетающую тарелку. А потом видеоряд с ДНК, клетками, людьми.
Было ли это самоубийство из-за того что его оставили на Земле, или он так провожал коллег по цеху, а те оставили ему подарок, или же он так порождал жизнь через свои страдания?
Дизайн интерфейсов
Интерфейс подобен палке слепого - он посредник между человеком и компьютерной средой. Хороший интерфейс не мешает пользователю и позволяет сфокусироваться человеку на работе. Пользователи не единственные участники процесса разработки. Эта статья - мини конспект курса лекций на Coursera.
Dark Knight Rises
Посмотрел нового бэтмана к Кристианом Бэйлом. Смешанные впечатления. С одной стороны - приятно видеть продолжение, с другой стороны - нелепых моментов стало больше и нет wow-эффекта от концовки, как было с Джокером.
Уэйн-старина ушёл на покой после прошлой серии, все винят бэтмана в убийстве главного прокурора, не зная что тот был злодеем, да и он сам никуда не хочет выбираться - личная жизнь после смерти любимой женщины не клеется.
Екклезиаст
Давно не читал Библии, открыл почитать Екклезиаста, а до этого послушал я лекцию Кураева где он упоминал о том, что у шумеров понятие прогресса и течения времени было обратным, их язык даже говорил о том что будущее сзади (через плечо), поэтому его не видно и смотреть надо в прошлое.
В этом свете Екклезиаст очень интересно читать. Вкратце, получив богатство и власть, увидел для себя царь фатализм, так свойственный современным циникам. Не это ли взгляд назад, на прошедшие круги?
Все идет в одно место: все произошло из праха и все возвратится в прах.Екклезиаст 3:20
Проектирование оповещений
Оповещения (notification) как правило о чём-то ( object = существительное = событие, дружба) что изменяется ( verb = глагол = добавлено, запрошено) кем-то ( actor = другим пользователем, системой) и кому-то показывается (userID = пользователю, группе, компании). По сути это модель естественного языка - на этом же основаны триплеты RDF.
Вот нормализованная структура данных, хотя я использовал Mongo.
Собеседование php разработчика - темы для обсуждения
Как работник, я часто ходил на собеседования и поэтому решил составить такой небольшой check-list для себя, но может пригодиться как работникам так и работодателям. Справа оставил место для заметок на случай если вы распечатаете. Отсортировано согласно логичному течению интервью