sudo python -m smtpd -n -c DebuggingServer localhost:25
Tuesday, June 9, 2015
How to setup a fake SMTP server to catch all mails?
Wednesday, March 18, 2015
MySQL logging - Логируем запросы к MySQL
Рано или поздно возникает необходимость логированя запросов, которые попадают на MySQL сервер. Это могут быть как slow query так и все запросы.
До версии 5.1.12 дожно было запустить mysql с параметром log
Если же нужна генерация в файл, то можно выполнить следующие запросы:
До версии 5.1.12 дожно было запустить mysql с параметром log
mysqld --log=log_file_nameили же записать в my.cnf параметр
log = log_file_nameНачиная с версии >= 5.1.12 имеем три параметра:
- --log-output=TABLE,FILE
- --general_log
- --slow-query-log
Либо же выполнив следующий запросы:
Table - это таблица в mysql.general_log, имеющая следующую структуру:SET global general_log = 1; SET global log_output = 'table';
CREATE TABLE `general_log` ( `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, `thread_id` bigint(21) unsigned NOT NULL, `server_id` int(10) unsigned NOT NULL, `command_type` varchar(64) NOT NULL, `argument` mediumtext NOT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'Для slow-query-log структура будет следующей:
CREATE TABLE `slow_log` ( `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, `query_time` time NOT NULL, `lock_time` time NOT NULL, `rows_sent` int(11) NOT NULL, `rows_examined` int(11) NOT NULL, `db` varchar(512) NOT NULL, `last_insert_id` int(11) NOT NULL, `insert_id` int(11) NOT NULL, `server_id` int(10) unsigned NOT NULL, `sql_text` mediumtext NOT NULL, `thread_id` bigint(21) unsigned NOT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
Если же нужна генерация в файл, то можно выполнить следующие запросы:
SET global log_output = 'FILE'; SET global general_log_file='/home/slava/mysql_queries.log'; SET global general_log = 1;
Sunday, March 15, 2015
Блог переезжает на новый домен - blog move to www.sundrop.info
Уважаемые читатели!
В связи с тем что 22-го марта истекает срок регистрации предыдущего домена, а регистрационные данные, увы, принадлежали не мне (будет мне уроком) и способа продлить домен я не нашел (ну не хотят GoDaddy брать деньги с меня) было принято решение переехать просто на новое доменное имя.
Итого, вместо www.sundrop.name имеем www.sundrop.info
У меня все!
В связи с тем что 22-го марта истекает срок регистрации предыдущего домена, а регистрационные данные, увы, принадлежали не мне (будет мне уроком) и способа продлить домен я не нашел (ну не хотят GoDaddy брать деньги с меня) было принято решение переехать просто на новое доменное имя.
Итого, вместо www.sundrop.name имеем www.sundrop.info
У меня все!
Thursday, December 11, 2014
Многопоточность в MFC (multithreading)
Поток – отдельная ветвь выполнения программы. Имеет свой стек и работает независимо от других потоков приложения.
Создание простейшего потока
AfxBeginThread(ProcName,param,priority)
ProcName – имя функции, которая будет выполнятся в новом потоке
param – указатель типа LPVOID или void* на аргумент ProcName
priority – константа, определяющая приоритет нового потока по отношению к основному
Может принимать одно из следующих значений:
1. Глобальная переменная
Объект событий CEvent может находится в одном из двух состояний – сигнализирует или молчит. Потоки отслеживают момент, когда объект события начинает сигнализировать, и начинаю выполнение операций.
- второй параметр – время отслеживания. INFINITE – бесконечно.
В момент установки события WaitForSingleObject() вернет управление потоку.
В момент сброса события поток должен прекратить свою работу.
Для этого надо организовать постоянный опрос состояния события.
Это можно сделать следующим способом:
Если результат вызова этой функции равен WAIT_OBJECT_0, то объект в остоянии сигнализации. В других случаях – молчит.
Синхронизация работы нескольких потоков
Для синхронизации нескольких потоков используют следующие объекты: критические секции, семафоры, защелки.
1. Критические секции.
Критические секции используются для контроля доступа к защищенным данным.
Их можно использовать внутри одного класса для синхронизации чтения-доступа к данным.
Из данного примера видно, что при записи нового значения невозможно прочитать старое. Соответственно при чтении значения его невозможно изменить. Если в работе участвуют большие объемы данных, то для предотвращения сбоя необходим контроль. Критические секции обеспечивают минимальную защиту от сбоев.
2. Защелки(MUTEXes)
Использование защелок CMutex при синхронизации потоков одного приложения не отличается от использования критических секций. Работа с ними осуществляется с использованием следующих объектов: CSingleLock и CMultiLock. Для получения доступа к защелке используется методо Lock(). Для освобождения защелки нужно вызвать метод Unlock()
3. Семафор
Использование этого объекта ничем не отличается от использования предыдущих. Разница заключается в том, что семафор дает право на использование контролируемых параметров определенному числу потоков. В семафоре хранится количество объектов, которые в данный момент имеют доступ к данным.
Создание простейшего потока
AfxBeginThread(ProcName,param,priority)
ProcName – имя функции, которая будет выполнятся в новом потоке
param – указатель типа LPVOID или void* на аргумент ProcName
priority – константа, определяющая приоритет нового потока по отношению к основному
Может принимать одно из следующих значений:
THREAD_PRIORITY_ABOVE_NORMAL // на один пункт ниже нормального THREAD_PRIORITY_BELOW_NORMAL //на один пункт выше нормального THREAD_PRIORITY_HIGHEST //на два пункта выше нормального THREAD_PRIORITY_IDLE //базовый приоритет равный 1 THREAD_PRIORITY_LOWEST //на два пункта ниже нормального THREAD_PRIORITY_NORMAL //нормальный приоритет THREAD_PRIORITY_TIME_CRITICAL //приоритет равный 15Приоритет потока определяет, как часто по отношению к другим выполняющимся потокам система будет передавать управление данному потоку
UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from Thread” ,MB_OK); return 0; } SomeFunc() { AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока }Синхронизация работы потоков.
1. Глобальная переменная
bool bThreadstop; //контрольная переменная UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); while(!bThreadstop) { //Выполнение опреаций } ::MessageBox((HWND)param, ”Thread ended”,”Message from thread”,MB_OK); return 0; } SomeFunc() { bThreadstop=false; AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока } StopThread() { bThreadstop=true; //остановка потока }2. Взаимодействие с помощью сообщений
const WM_THREADENDED = WM_USER+1; //Это надо добавить в катры сообщений afx_msg LONG OnThreadEnded(WPARAM wParam,LPARAM lParam); ON_MESSAGE(WM_THREADENDDED,OnThreadEnded) bool bThreadstop; //контрольная переменная UINT ThreadProc(LPVOID param) //Создание потоковой функции { ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); while(!bThreadstop) { //Выполнение опреаций } ::PostMessage((HWND)param,WM_THREADENDED,(WPARAM)param,0); //Сообщение return 0; } SomeFunc() { bThreadstop=false; AfxBeginThread(ThreadProc,GetSafeHwnd()); //Запуск потока } StopThread() { bThreadstop=true; //остановка потока } LONG OnThreadEnded(WPARAM wParam, LPARAM lParam) { ::MessageBox((HWND)wParam,”Thread Ended”,”Message from thread”, MB_OK); } //Данный пример закрывает главное окно после выполнения потоковой функции3. Взаимодействие с помощью объектов событий
Объект событий CEvent может находится в одном из двух состояний – сигнализирует или молчит. Потоки отслеживают момент, когда объект события начинает сигнализировать, и начинаю выполнение операций.
CEvent ThreadStart; //объект автоматически устанавливается в состояние молчания ThreadStart.SetEvent(); //установка состояния сигнализацииОтслеживание состояния объекта осуществляется с помощью функции WinAPI WaitForSingleObject();
:: WaitForSingleObject(ThreadStart.m_hObject,INFINITE);- первый параметр – дескриптор отслеживаемого события.
- второй параметр – время отслеживания. INFINITE – бесконечно.
В момент установки события WaitForSingleObject() вернет управление потоку.
В момент сброса события поток должен прекратить свою работу.
Для этого надо организовать постоянный опрос состояния события.
Это можно сделать следующим способом:
::WaitForSingleObject(ThreadStart.m_hObject,0);Время 0 говорит о том, что надо опросить событие.
Если результат вызова этой функции равен WAIT_OBJECT_0, то объект в остоянии сигнализации. В других случаях – молчит.
CEvent ThreadStart; //Объект начала работы потока CEvent ThreadEnd; //Объект окончания работы потока UINT ThreadProc(LPVOID param) //Создание потоковой функции { :: WaitForSingleObject(ThreadStart.m_hObject,INFINITE); //ожидание запуска потока ::MessageBox((HWND)param, ”Thread activated”,”Message from thread”,MB_OK); bool Running=true; int result; while(Running) { //Выполнение опреаций result=:: WaitForSingleObject(ThreadEnd.m_hObject,0); //проверка завершения if(result==WAIT_OBJECT_0) Running=false; } ::PostMessage((HWND)param,WM_CLOSE,0,0); //Сообщение return 0; } Start() //запуск потока { ThreadStart.SetEvent(); } End() //завершение потока { ThreadEnd.SetEvent(); }Поток нужно создавать независимо от состояния событий.
Синхронизация работы нескольких потоков
Для синхронизации нескольких потоков используют следующие объекты: критические секции, семафоры, защелки.
1. Критические секции.
Критические секции используются для контроля доступа к защищенным данным.
Их можно использовать внутри одного класса для синхронизации чтения-доступа к данным.
class cls { private: int val; CCriticalSection section; public: void write(int); void read(int*); } void cls::write(int n) { section.Lock(); val=n; section.Unlock(); } void cls::read(int * n) { section.Lock(); *n=val; section.Unlock(); }При вызове метода Lock() происходит блокировка секции, и последующие вызовы этого метода не возвратят управление вызывающему потоку до тех пор, пока секция не будет освобождена.
Из данного примера видно, что при записи нового значения невозможно прочитать старое. Соответственно при чтении значения его невозможно изменить. Если в работе участвуют большие объемы данных, то для предотвращения сбоя необходим контроль. Критические секции обеспечивают минимальную защиту от сбоев.
2. Защелки(MUTEXes)
Использование защелок CMutex при синхронизации потоков одного приложения не отличается от использования критических секций. Работа с ними осуществляется с использованием следующих объектов: CSingleLock и CMultiLock. Для получения доступа к защелке используется методо Lock(). Для освобождения защелки нужно вызвать метод Unlock()
CMutex mutex; //создание защелки CSingleLock sLock(&mutex); //захват защелки sLock.Lock(); sLock.Unlock(); //освобождение защелки class cls { private: int val; CMutex mutex; public: void write(int); void read(int*); } void cls::write(int n) { CSingleLock sLock(&mutex); sLock.Lock(); val=n; } void cls::read(int * n) { CSingleLock sLock(&mutex); sLock.Lock(); *n=val; }Использование метода Unlock() в данном случае необязательно т.к. при вызове деструктора sLock защелка автоматически освобождается.
3. Семафор
Использование этого объекта ничем не отличается от использования предыдущих. Разница заключается в том, что семафор дает право на использование контролируемых параметров определенному числу потоков. В семафоре хранится количество объектов, которые в данный момент имеют доступ к данным.
CSemaphore semaphore(2,2); //создание семафораПри создании семафора указывается начальное и максимальное значение счетчика
CSingleLock sLock(&semaphore); //Захват семафора sLock.Lock();При вызове метода Lock() значение счетчика внутри семафора уменьшается. Когда оно достигнет нуля, метод Lock() будет ждать освобождения семафора. После этого захватит семафор и вернет управление вызывающей функции
sLock.Unlock(); //Освобождение семафора
Tuesday, December 9, 2014
Закон Конвея - Conway's law
Итак, Джон Конвей когда-то заявил что:
Или если у вас есть 2 офшорные команды, то и проект будет состоять из двух частей.
Причем если эти команды тесно общаются, например устраивая ежедневные skype митинги и вообще, то и модули будут тесно связаны — например единая сборка, репозиторий, документация, трекер, но разные библиотеки лежащие рядом. Но если общаются лишь переписываясь по email, то получите связь через какой нибудь RESTful API.
Десятки раз видел подобные примеры.
Или, как сказал Эрик Реймонд:
Organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizationsчто можно перевести как:
Организация которая разрабатывает систему ... вынуждена делать систему по структуре повторяющую структуру коммуникаций внутри организацииВ общем если в компании разрабатывающей ПО есть 3 отдела, которые занимаются этим проектом, то он, с точки зрения архитектуры, будет представлять из себя 3 больших модуля.
Или если у вас есть 2 офшорные команды, то и проект будет состоять из двух частей.
Причем если эти команды тесно общаются, например устраивая ежедневные skype митинги и вообще, то и модули будут тесно связаны — например единая сборка, репозиторий, документация, трекер, но разные библиотеки лежащие рядом. Но если общаются лишь переписываясь по email, то получите связь через какой нибудь RESTful API.
Десятки раз видел подобные примеры.
Или, как сказал Эрик Реймонд:
Если у вас есть 4 команды разрабатывающие один компилятор — вы получите компилятор работающий в 4 прохода (4-pass compiler)См. закон на википедии: Conway's law
Friday, November 7, 2014
PHP: конструктор по умолчанию (default constructors)
Рассмотрим следующий код:
В данном коде представлена простая иерархия классов.
Теперь посмотрим на 12-ую строку кода отмеченную (?). Конечно, в данном случае мы можем не вызывать родительский конструктор, но...
Предположим, со временем мы дополнили родительский класс:
Вроде бы, мы ничего не поменяли, но теперь все наследуемые классы работают неверно, т.к. не вызывают родительский конструктор. Для того чтобы это исправить, нам нужно пройтись по всем классам потомкам и добавить вызов родительского конструктора.
Мы могли бы избежать этой проблемы, если бы придерживались простого правила: вставлять вызов родительского конструктора, даже когда он пустой. Если родительский конструктор не определен, то вызов parent::__construct() не будет делать ровным счетом ничего. Но, если мы когда либо внедрим родительский конструктор, все наши дочерние классы будут готовы.
- class Animal {
- protected $what = "nothing";
- function sound() {
- echo get_class($this)." says {$this->what}";
- }
- }
- class Cow extends Animal {
- protected $what = "moo";
- protected $owner;
- public function __construct($owner) {
- // parent::__construct(); (?)
- $this->owner = $owner;
- }
- }
- $a = new Cow("Old McDonald");
- $a->sound();
Теперь посмотрим на 12-ую строку кода отмеченную (?). Конечно, в данном случае мы можем не вызывать родительский конструктор, но...
Предположим, со временем мы дополнили родительский класс:
- class Animal {
- protected $born;
- public function __construct() {
- $this->born = time();
- }
- }
Мы могли бы избежать этой проблемы, если бы придерживались простого правила: вставлять вызов родительского конструктора, даже когда он пустой. Если родительский конструктор не определен, то вызов parent::__construct() не будет делать ровным счетом ничего. Но, если мы когда либо внедрим родительский конструктор, все наши дочерние классы будут готовы.
Saturday, July 5, 2014
Вопросы для IT-собеседования - Questions for IT interview
Вопросы для IT-собеседования:
— Вы ранее привлекались за хранение данных в глобальных переменных?
— Какой результат выполнения команды git push me and then just touch me till I can get my satisfaction, satisfaction?
— Найдите точку G бинарным поиском
— Вы когда-нибудь делали .Net за деньги?
— Вы способны довести девушку до оргазма языком программирования?
— В своём резюме вы указали знание Delphi. вам не стыдно?
— Почему люк скайуокер круглый?
— Какой из циклов быстрее, for, while или правило буравчика? оО
— Перед вами кисть, холст и мольберт. напишите компилятор
— Расскажите что-нибудь про Pascal
— Как часто вы говорите своему коду "ну пожалуйста.."?
— У кого был самый длинный код в вашей прошлой команде?
— Вы моете руки перед правкой кода на продакшне?
— Вас раньше обвиняли в попытках программирования?
— Ну признайтесь уже — джаваскрипт алертами дебажили?
— Можете ли вы провести аналогию между работой на пятилетнем проекте и проктологией?
— Что, по-вашему мнению, более эффективно: скопипастить код из примеров или убедить заказчика, что ему не нужна эта фича?
— Если честно, то нас немного смущает тот факт, что вы искали работу программиста через биржу труда...
— Согласны ли вы что каждый девелопер должен посадить зрение, построить велосипед и вырастить репозиторий?
— В своем резюме вы указали, что хотели бы поработать на интересном проекте... вы этот проект с собой принесли?
— Правда ли, что смесь php, css, js, html и sql в одном файле имеет слабительный эффект?
— Согласны ли вы, что у админа должна быть борода, даже если админ — женщина?
— Скажите, вы когда-нибудь симулировали ООП?
— Каким вы видите свой код через пять лет?
— Xbox, PlayStation или Terminal — какую консоль предпочитаете?
— Вас когда-нибудь запирали в серверной? За что?
— 2048 или “Косынка” — в чём вы более успешны?
— Вы толерантны к копипастам?
— Цикл, условие, переменная — а какие еще термины из С++ вы знаете, чтобы отказать парню?
— Цой, Ленин, Delphi — что между ними общего?
— Как объяснить джуниору что пинговать сервера в его возрасте – это нормально?
— Назовите самое экстремальное место в котором вы занимались багфиксингом
— Напишите простейшую операционную систему. уложитесь в 140 символов
— Как вы относитесь к легализации курения мануалов?
— Вы ранее привлекались за хранение данных в глобальных переменных?
— Какой результат выполнения команды git push me and then just touch me till I can get my satisfaction, satisfaction?
— Найдите точку G бинарным поиском
— Вы когда-нибудь делали .Net за деньги?
— Вы способны довести девушку до оргазма языком программирования?
— В своём резюме вы указали знание Delphi. вам не стыдно?
— Почему люк скайуокер круглый?
— Какой из циклов быстрее, for, while или правило буравчика? оО
— Перед вами кисть, холст и мольберт. напишите компилятор
— Расскажите что-нибудь про Pascal
— Как часто вы говорите своему коду "ну пожалуйста.."?
— У кого был самый длинный код в вашей прошлой команде?
— Вы моете руки перед правкой кода на продакшне?
— Вас раньше обвиняли в попытках программирования?
— Ну признайтесь уже — джаваскрипт алертами дебажили?
— Можете ли вы провести аналогию между работой на пятилетнем проекте и проктологией?
— Что, по-вашему мнению, более эффективно: скопипастить код из примеров или убедить заказчика, что ему не нужна эта фича?
— Если честно, то нас немного смущает тот факт, что вы искали работу программиста через биржу труда...
— Согласны ли вы что каждый девелопер должен посадить зрение, построить велосипед и вырастить репозиторий?
— В своем резюме вы указали, что хотели бы поработать на интересном проекте... вы этот проект с собой принесли?
— Правда ли, что смесь php, css, js, html и sql в одном файле имеет слабительный эффект?
— Согласны ли вы, что у админа должна быть борода, даже если админ — женщина?
— Скажите, вы когда-нибудь симулировали ООП?
— Каким вы видите свой код через пять лет?
— Xbox, PlayStation или Terminal — какую консоль предпочитаете?
— Вас когда-нибудь запирали в серверной? За что?
— 2048 или “Косынка” — в чём вы более успешны?
— Вы толерантны к копипастам?
— Цикл, условие, переменная — а какие еще термины из С++ вы знаете, чтобы отказать парню?
— Цой, Ленин, Delphi — что между ними общего?
— Как объяснить джуниору что пинговать сервера в его возрасте – это нормально?
— Назовите самое экстремальное место в котором вы занимались багфиксингом
— Напишите простейшую операционную систему. уложитесь в 140 символов
— Как вы относитесь к легализации курения мануалов?
Subscribe to:
Posts (Atom)