Страницы

воскресенье, 4 декабря 2011 г.

ajax api

Представляю простенький сервис для выполнение кросс-доменных ajax запросов. Все подробности
тут . Собственно это обертка к моему прокси написаному на эрланге и javascriptm, который передает запросы посредством тега <script>. Юзайте на здоровье, скоро будет еще одна вкусность.

понедельник, 7 ноября 2011 г.

Долго не писал, зато теперь есть Poster

Топики о плагинах к firefox получили логичное продолжение в простеньком сервисе, который
я назвал Poster. Вот здесь можно сделать плагин под свой сайт для быстрого и удобного добавления
контента на него, как вами, так и вашими пользователями.
P.S
Еще один удобный сервис ajaxapi, для cross domain ajax, так задрала эта проблема, что решил ее решить для себя раз и навсегда.

среда, 14 сентября 2011 г.

Лекарство от нагрузок

Не безизвестная компания эрикссон является разработчиком замечательного языка Erlang. Эта штука на уровне языка реализовала работу с процессами. Более того - эти процессы легковесны. Так же в стандартную поставку входят библиотека готовых паттернов, которые можно знать, а можно и не знать.
Собственно к чем это я. А к тому, что учавствую в проекте написанном на эрланге. Нагрузка что-то типа 20 запросов в секунду, собственно приложение держит нагрузку без каких-либо проблем. Но иногда может и поперхнуться, как правило связано это с работой с базой данных. Система резервного так сказать восстановления не срабатывает. Как оказалось проблема в драйвере mysql, который начинал себя неадекватно вести после обрыва сетевого соединения, а потом его восстановления. Из данной довольно неприятной ситуации для меня, сделал вывод, что системы резервных каналов, дополнительных утилит контроля , да вообще везде, где подрозумеватся слово резервный - должны быть реализованы при помощи другой технологии, а не основной, на котором разработана основная логика .

P.S
vivat perl, vivat perl

понедельник, 6 июня 2011 г.

Просто мысль

Чего-то потянуло не на специализированую тему. Наткнулся на новость об очередном взломе
инфраструктуры Sony тут.
При этом вспомнил, что горячо любимые всем английские ученые, проведя опрос, пришли к выводу,
что IT- работники главная причина информационной безопасности компаний, а там и не только до информационной недалеко. И само-собой прошерстил в мозгу сколько инфы я унес из компании, откуда уволился. В общем все больше укоряняюсь в мысли, что власть в этом мире довольно иллюзорная штука,
что возможностей ее реализации у простейшего офисного айтишника гораздо больше, чем он может представить, и ограничивается лишь его воображением. А сколько тогда у не простого! Например администратора базы пентагона, там они тоже есть! И не говорите мне про системы безопасности, их тоже разрабатывали ...да программисты. И не рассказывайте, что их код проверяли, это уже смешно любому человеку, который хоть раз разбирал индусский код.

понедельник, 16 мая 2011 г.

Не слушайте

Не слушайте их, когда они говорят, что ваша идея бесперспективна.
Когда говорят, что идея должна быть Идеей.
Эти перфекционисты, мой бог, они говорят вам, что лучше потратить год на отладку.
Они говорят, что пользователи капризны и не примут проект с недоработками.
Вы предпочитаете слушать их? Тех, которые из-за своего перфекционизма сами ничего не запустили?
Это лучшая отмазка для тех, кто не хочет пытаться – «Либо надо сделать идеально, либо не делать.»
Идеал недостижим. Нет предела совершенству. Проект всегда будет недоработан. Такова природа бытия.
Поэтому, не тяните. Не тяните с запуском стартапа.
Энтузиазм пропадает. Появляются новые идеи. Меняются планы.
Просто запускайте, поглощайте критику, улучшайте. Главное – это готовая основа.

Не слушайте их. Слушайте себя.

вторник, 10 мая 2011 г.

Use perl или продолжаем оптимизацию

Бродил по коду проекта на новой работе и набрел на такую вот функцию :


sub translit
{
my $text = shift;
$text = "$text";

$text =~ s/А/A/g;
$text =~ s/Б/B/g;
$text =~ s/В/V/g;
$text =~ s/Г/G/g;
$text =~ s/Д/D/g;
$text =~ s/Е/E/g;
$text =~ s/Ё/E/g;
$text =~ s/Ж/ZCH/g;
$text =~ s/З/Z/g;
$text =~ s/И/I/g;
$text =~ s/Й/J/g;
$text =~ s/К/K/g;
$text =~ s/Л/L/g;
$text =~ s/М/M/g;
$text =~ s/Н/N/g;
$text =~ s/О/O/g;
$text =~ s/П/P/g;
$text =~ s/Р/R/g;
$text =~ s/С/S/g;
$text =~ s/Т/T/g;
$text =~ s/У/U/g;
$text =~ s/Ф/F/g;
$text =~ s/Х/H/g;
$text =~ s/Ц/C/g;
$text =~ s/Ч/CH/g;
$text =~ s/Ш/SH/g;
$text =~ s/Щ/SCH/g;
$text =~ s/Ь/'/g;
$text =~ s/Ъ/'/g;
$text =~ s/Ы/Y/g;
$text =~ s/Э/E/g;
$text =~ s/Ю/YU/g;
$text =~ s/Я/YA/g;
$text =~ s/а/a/g;
$text =~ s/б/b/g;
$text =~ s/в/v/g;
$text =~ s/г/g/g;
$text =~ s/д/d/g;
$text =~ s/е/e/g;
$text =~ s/ё/e/g;
$text =~ s/ж/zch/g;
$text =~ s/з/z/g;
$text =~ s/и/i/g;
$text =~ s/й/j/g;
$text =~ s/к/k/g;
$text =~ s/л/l/g;
$text =~ s/м/m/g;
$text =~ s/н/n/g;
$text =~ s/о/o/g;
$text =~ s/п/p/g;
$text =~ s/р/r/g;
$text =~ s/с/s/g;
$text =~ s/т/t/g;
$text =~ s/у/u/g;
$text =~ s/ф/f/g;
$text =~ s/х/h/g;
$text =~ s/ц/c/g;
$text =~ s/ч/ch/g;
$text =~ s/ш/sh/g;
$text =~ s/щ/sch/g;
$text =~ s/ь/'/g;
$text =~ s/ъ/'/g;
$text =~ s/ы/y/g;
$text =~ s/э/e/g;
$text =~ s/ю/yu/g;
$text =~ s/я/ya/g;
$text =~ s/і/i/g;
$text =~ s/ї/yi/g;
$text =~ s/є/e/g;

return $text;
}


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


sub translit_new_cycle
{
my $text = shift;
my %hash_=(
'А'=>'A',
'Б'=>'B',
'В'=>'V',
'Г'=>'G',
'Д'=>'D',
'Е'=>'E',
'Ё'=>'E',
'Ж'=>'ZCH',
'З'=>'Z',
'И'=>'I',
'Й'=>'J',
'К'=>'K',
'Л'=>'L',
'М'=>'M',
'Н'=>'N',
'О'=>'O',
'П'=>'P',
'Р'=>'R',
'С'=>'S',
'Т'=>'T',
'У'=>'U',
'Ф'=>'F',
'Х'=>'H',
'Ц'=>'C',
'Ч'=>'CH',
'Ш'=>'SH',
'Щ'=>'SCH',
'Ь'=>"'",
'Ъ'=>"'",
'Ы'=>'Y',
'Э'=>'E',
'Ю'=>'YU',
'Я'=>'YA',
'а'=>'a',
'б'=>'b',
'в'=>'v',
'г'=>'g',
'д'=>'d',
'е'=>'e',
'ё'=>'e',
'ж'=>'zch',
'з'=>'z',
'и'=>'i',
'й'=>'j',
'к'=>'k',
'л'=>'l',
'м'=>'m',
'н'=>'n',
'о'=>'o',
'п'=>'p',
'р'=>'r',
'с'=>'s',
'т'=>'t',
'у'=>'u',
'ф'=>'f',
'х'=>'h',
'ц'=>'c',
'ч'=>'ch',
'ш'=>'sh',
'щ'=>'sch',
'ь'=>"'",
'ъ'=>"'",
'ы'=>'y',
'э'=>'e',
'ю'=>'yu',
'я'=>'ya',
'і'=>'i',
'ї'=>'yi',
'є'=>'e',
' '=>' ',
"\n"=>"\n"

);
my @a=split(//,$text);
foreach(@a){
$_=$hash_{$_};
}


#
return join("",@a);
}


А теперь тестируем и...

#!/usr/bin/perl
use strict;
use Benchmark qw(:all);
use Data::Dumper;
use utf8;


my @a=(
"Я родил собаку это меня убило как же все тупо Я родил собаку это меня убило как же все тупо"

);


my $count=100000;

foreach(@a){
timethese($count, {
'may be good' => "translit_new_cycle('$_')",
'may be bad' => "translit('$_')",
});
}


получаем

may be bad: 11 wallclock secs (10.24 usr + 0.00 sys = 10.24 CPU) @ 9765.62/s (n=100000)
may be good: 12 wallclock secs (10.45 usr + 0.00 sys = 10.45 CPU) @ 9569.38/s (n=100000)

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

Benchmark: timing 100000 iterations of may be bad, may be good...
may be bad: 3 wallclock secs ( 2.63 usr + 0.00 sys = 2.63 CPU) @ 38022.81/s (n=100000)
may be good: 5 wallclock secs ( 4.96 usr + 0.00 sys = 4.96 CPU) @ 20161.29/s (n=100000)


Но увеличившая разница во времени( почти в два раза) насторожила, введем очень длинную строку для тестов "Я родил собаку родил собаку это меня убило как же все тупо родил собаку это меня убило как же все тупо родил собаку это меня убило как же все тупо родил собаку это меня убило как же все тупо"

may be bad: 22 wallclock secs (18.29 usr + 0.02 sys = 18.31 CPU) @ 5461.50/s (n=100000)
may be good: 22 wallclock secs (17.58 usr + 0.01 sys = 17.59 CPU) @ 5685.05/s (n=100000)



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

my %hash_=(
'А'=>'A',
'Б'=>'B',
'В'=>'V',
'Г'=>'G',
'Д'=>'D',
'Е'=>'E',
'Ё'=>'E',
'Ж'=>'ZCH',
'З'=>'Z',
'И'=>'I',
'Й'=>'J',
'К'=>'K',
'Л'=>'L',
'М'=>'M',
'Н'=>'N',
'О'=>'O',
'П'=>'P',
'Р'=>'R',
'С'=>'S',
'Т'=>'T',
'У'=>'U',
'Ф'=>'F',
'Х'=>'H',
'Ц'=>'C',
'Ч'=>'CH',
'Ш'=>'SH',
'Щ'=>'SCH',
'Ь'=>"'",
'Ъ'=>"'",
'Ы'=>'Y',
'Э'=>'E',
'Ю'=>'YU',
'Я'=>'YA',
'а'=>'a',
'б'=>'b',
'в'=>'v',
'г'=>'g',
'д'=>'d',
'е'=>'e',
'ё'=>'e',
'ж'=>'zch',
'з'=>'z',
'и'=>'i',
'й'=>'j',
'к'=>'k',
'л'=>'l',
'м'=>'m',
'н'=>'n',
'о'=>'o',
'п'=>'p',
'р'=>'r',
'с'=>'s',
'т'=>'t',
'у'=>'u',
'ф'=>'f',
'х'=>'h',
'ц'=>'c',
'ч'=>'ch',
'ш'=>'sh',
'щ'=>'sch',
'ь'=>"'",
'ъ'=>"'",
'ы'=>'y',
'э'=>'e',
'ю'=>'yu',
'я'=>'ya',
'і'=>'i',
'ї'=>'yi',
'є'=>'e',
' '=>' ',
"\n"=>"\n"

);

sub translit_new_cycle
{
my $text = shift;

my @a=split(//,$text);
foreach(@a){
$_=$hash_{$_};
}


#
return join("",@a);
}


то получим наконец то, что ожидали...Хотя в принципе можно и лучше, например если заменить хеш, массивом, а цикл развернуть, так как длинна смс все таки фиксированная..


may be bad: 23 wallclock secs (18.13 usr + 0.00 sys = 18.13 CPU) @ 5515.72/s (n=100000)
may be good: 17 wallclock secs (13.86 usr + 0.02 sys = 13.88 CPU) @ 7204.61/s (n=100000)

На более коротких текстах типа SMS, наша процедура выигрывает с преимуществом в два раза.

Собственно к чему я это...Наверно к тому что панацеи не существует

пятница, 29 апреля 2011 г.

Очень полезная штука

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

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

качать а заодно слегка читать здесь

понедельник, 25 апреля 2011 г.

Python и Perl

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


d=",".join([ str(i) for i in range(0,10000)] )


Понял, что что-то два эти языка роднит, и это за областью синтаксиса или языковых конструкций.
Значит, что это что-то фундаментальней и общей, и понял...
Понял, что это совобода - python-у абсолютно подойдет лозунг "it's more than one way to do it". И вольностей в обращение с операторами у него ничуть не меньше чем в Perl, чего стоит хотя бы добавление свойств класса прям на лету. Значит ли, что он повторит судьбу Perl - медленного превращение в инструмент аутентичных разработчиков? На этот вопрос трудно дать ответ. Зато точно знаю, что некоторые системные функции нельзя давать переопределять, по крайней мере таким простым способом :

str=" privet world "


P.S
   Долго не мог оддуплиться, что было не так

P.S.S
   Оказалось некоторые не замечают подвоха в последней строчке кода на python, поэтому посню. Данный код определяет переменную, но имя str зарезервировано для встроенной функции str, приведения к строчному виду любого переданного объекта, и она используется повсеместно, собственно у меня падал из-за этого django процесс. Этот код переопределяет ее без каких-то зазрений совести, что собственно у меня не вызвало кстати удивления, покорил себя немного за невнимательность.

воскресенье, 24 апреля 2011 г.

Еще немного о том, как себя заставлять..

Ответить на вопрос «Как себя заставлять?» невозможно. Невозможно не потому что себя заставить нельзя, а потому что сама идея является неверной с самого начала.

Проблема самозаставления возникает тогда, когда у человека нету контакта с собой. То есть, модель себя, присутствующая у него в голове, не соответствует действительности. Мы же редко ищем и формулируем сведения о себе. А обращаем внимание на тонкости и изменения — и того реже, хотя они самые важные.

В результате этого возникает отсутствие контакта с собой, в результате которого возникает раздвоенность сознания и личности, в результате которой сознание думает одно, а личность делает совсем другое, в результате чего и возникает проблема «Как себя заставлять?».

Никак.

Нужно лечить причину.

источник http://habrahabr.ru/blogs/gtd/118049/

Мой новый способ перестать страдать фигней и начать работать

В операционных системах есть такая штука, как планирощик задачь. Многозадачность довольна илюзорная - на самом деле все выполняется последовательно( спасибо КЕП). Самый простейший планирощик задач основан на приоритетах - то есть каждому процессу присваивается приоритет, на их основе выделяется кванты времени на выполнения, и последовательность. При этом возникает проблема, что малоприоритетные задачи могут никогда не быть выполненны. Так вот не кажется вам,что частенько человек работает именно по такому принципу. Да-да...А у еще вот у него бывает такое, видя задачу уже поставил ее в начало списка...ему так влом начинать ее делать...она ж большая...хочеться ее разбить. Короче не хочеться даже начинать...Ну вообщем тупик, потому сначала делаем самое пишем самое незначительно, что надо было написать...Я вот написал скрипт, который все картинки ресайзит с задаными параметрами и складует ее в папку..

#!/usr/bin/perl

use GD;
my $PERCENT=shift;#насколько процентов уменьшить картинку

my $PROC_DIR=shift;#куда сложить копии

use File::Find;
mkdir($PROC_DIR);

finddepth(\&wanted, ("./") );
exit(0);
sub wanted{
my $tmp=lc $_;
return unless($tmp=~/([\d]+)\.(png)$|([\d]+)\.(jpeg)$|([\d]+)\.(jpg)$|([\d]+)\.(gif)$/);

resize_save2thumbs($_);

}


sub resize_save2thumbs{

my ($image,$image_save)=@_;



my $thumb_img=GD::Image->new($image) or die $!;

my ($width,$height) = $thumb_img->getBounds();
my $new_height=($height/100)*$PERCENT;

my $kow=$new_height/$height;

my $new_width=$width*$kow;

my $new_thumb_img=GD::Image->new($new_width,$new_height);

$new_thumb_img->copyResampled($thumb_img,0,0, 0,0,$new_width,$new_height,$width,$height);


my $jpg_data = $new_thumb_img->jpeg;


open(FL,">$PROC_DIR$image".'.jpg') or die $!;

print FL $jpg_data;

close(FL);
}

вторник, 22 марта 2011 г.

FireFox не любит рекурсий

Если писать много и сложно, то может случиться так, что fireFox вдруг решит выпендриться и написать too many recursions и скрипт дальше отказываеться работать вообще.. Ты начинаешь лихорадочно искать, где ж у меня рекурсия, может она и есть, но тут лучше скажу про другой нюанс. JavaScript использует механизм замыкания, через него мы любим создавать объекты. Так вот это тоже подпадает под это гениальное сообщение в консоли ошибок..

Например...

function Rect(x_,y_,x1_,y2_){
this.x=x_;
this.y=y_;
this.x1=x1_;
this.y1=y1_;
this.some_func(i){
////
this.x+=i;
this.y+=i;


///

}

};

function some_func(){

for(var f=0;f<10000;f++){
var r=new Rect(f,f,f+100,f+100);
r.some_func(f/199);


}
return true;

}
Если очень упорствовать, то можно в цикле нарваться на сообщение too many recursions.. То есть злоупотреблять с созданием объектов не стоит. Прям аналогии с С++ и выделением памяти.

Удаление всех элементов массива

Вроде нет ничего проще....Но гениальных вариантов дофига, как оказалось
можно например в цикле делать pop каждому...Страшно॥Да ;)
Ладно долго страдал вот такой формой

var ar=new Array();
ar.push(7);
ar=[]; //delete all


А потом вчитавшись в документацию начал делать так вот

var ar=new Array();
ar.push(7);
ar.length=0; //delete all
Последнее понравилось больше...

пятница, 4 февраля 2011 г.

Использование алгоритма AES при помощи библиотеки openssl

Столкнулся с тем, что нет описания интерфейс к алгоритму AES в библиотеке OpenSSL, а несколько русскоязычных статей оказались мало пригодно, по тому простому поводу, что в примерах давали не работающий код. Хотя нельзя отрицать, что там была и полезная информация, которая помогла лучше понять англоязычную документацию на openssl.org .
Собственно функция фишрования :
unsigned long int do_crypt(unsigned char *infile,int inlen ,unsigned char * key)
{
// unsigned char key[32]; /* 256- битный ключ */
unsigned char *last_buf;//for last bytes that is
int sum_len=0;
int outlen=0;
EVP_CIPHER_CTX ctx;
const EVP_CIPHER * cipher;
/* Обнуляем структуру контекста */
EVP_CIPHER_CTX_init(&ctx);
/* Выбираем алгоритм шифрования */
cipher = EVP_aes_256_cbc();
/* Инициализируем контекст алгоритма */
EVP_EncryptInit(&ctx, cipher, key, NULL);
/* Шифруем данные */
last_buf=infile;
if(!EVP_EncryptUpdate(&ctx, last_buf, &outlen, infile,inlen ) ) return 0;
sum_len+=outlen;
last_buf=infile+outlen;
if(!EVP_EncryptFinal(&ctx, last_buf, &outlen)) return 0;
sum_len+=outlen;
EVP_CIPHER_CTX_cleanup(&ctx);
return sum_len;//возвращаем длину зашифрованых данных



};
Собственно функция принимает указатель на строку, которую надо зашифровать, длинну строки и ключ ( 256 бит в данном случае). Данная функция справляется нормально с шифрованием данных до 65 мегабайт, больше не тестировал. Возвращает длину зашифрованных данных, которая может отличаться от исходной длинны.
Функция дешифрования :

int do_decrypt(unsigned char *infile,int inlen,unsigned char * key)
{
unsigned char *last_buf;//for last bytes that is
int outlen,sum_len,temp_len,last;


EVP_CIPHER_CTX ctx;

const EVP_CIPHER * cipher;
/* Обнуляем структуру контекста */
EVP_CIPHER_CTX_init(&ctx);
/* Выбираем алгоритм шифрования */

cipher = EVP_aes_256_cbc();
/* Инициализируем контекст алгоритма */
EVP_DecryptInit(&ctx, cipher, key, NULL);
outlen=temp_len=0;
last_buf=infile;
if(!EVP_DecryptUpdate(&ctx, last_buf, &outlen,infile, inlen)) return 0;
memcpy(infile,last_buf,outlen);
last_buf=infile+outlen;
if(!EVP_DecryptFinal(&ctx, last_buf, &temp_len)) return 0;
memcpy(infile+outlen,last_buf,temp_len);

EVP_CIPHER_CTX_cleanup(&ctx);

return outlen+temp_len;
}


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

*(infile+outlen+temp_len)='\0';

вторник, 18 января 2011 г.

Тестировщику на заметку

Недавно наткнулся на статью про тестирование на http://habrahabr.ru, там кроме
всего прочего был в комментариях тезис :

"Тестирование относительно новая область, теоретическая база отсутствует"
С которым категорически не согласен, во всех аспектах, тестирование появилось вместе с программированием. Дальше вы мне возразите "Но им не занимались профессионально". Ага как же?! Им занимались профессионалы почище нас с вами. Так как в далекие 80-е - 90-е годы программирование было уделом институтов с перфокартами, то соответственно сложным программированием занимались люди владеющие на нормальном уровне "Теорией Вероятности" а так же "Теорией Планирование Экспериментов", которая и по сути является прототипом нынешней теоретической базы тестирования. Разрабатывалось, в частности, данное направление академиком МГУ В.В Налимов.

P.S
Я не ботан- асспирант в университете, не преподователь университета, не был заучкой( у меня порядочно троек есть), хоть и магистр.

P.S.S
Все придумано до нас