Skip to content

Хак при добавлении Canvas URL в Facebook

Для оптимизации и ускорения работы приложение в социальное сети Facebook хорошей практикой является размещение приложения на CDN, но возникает небольшая проблема при добавлении такого приложения. Для проверки приложения Facebook отправляет POST запрос на указанный Canvas URL, но мало какие CDN правильно отрабатывают такие запросы, я даже не знаю какие обрабатывают их правильно. Ведь для статики по логике не нужны POST запросы. Кто-то для решения этой проблемы размещает индексный файл Canvas URL отдельно от всей статики, где POST запрос без проблем обрабатывается. Впринципе решение, но приходится отслеживать и синхронизировать два независимых хранилища. Как показала практика эту проблему можно решить при помощи 301 редиректа.
Отправная точка есть, а тут уж каждый может решать как хочет:
1) Использовать сокращатель ссылок, например, bit.ly, который делает 301 редирект на нужную ссылку + помимо этого bit.ly поддерживает SSL, что позволяет нам указывать его и как Secure Canvas URL. Итоговая ссылка, которую пропускает Facebook выглядит так: https://bit.ly:443/shortenhash
2) Ваше приложение не на все 100% состоит из статики, а значит есть сервер где есть какой-нибудь web-server, можно на базе этого сервер реализовать такую же схему как и в первом пункте

Пять причин, которые тормозят развитие стартапа

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

1. Ожидание того, что всё будет идеально
Иногда очень трудно сдвинуться с места из-за ожидания того, что всё должно быть сразу идеально.
Вся сложность в том, что идеально быть не может, этому всегда будет что-то мешать. А ведь стартап на то и стартап, что он будет развиваться из идеи и совершенствоваться в процессе развития.

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

3. Делать всё самому
Не пытайтесь всё завязывать на себя одного, делегируйте задачи своим специалистам. Вы не можете знать все области сразу.

4. Становиться слишком серьезным
Принимая всё больше серьезных и даже критических решений, старайтесь оставаться открытым. Это добавит легкости в ваш коллектив.

5. Бояться поражений
Ошибиться можно всегда и не надо за это себя осуждать. Надо быть готовым к поражениям, они неизбежны. Принимая поражения слишком близко, можно перестать принимать решения вновь, так как это заранее будет вас пугать.

Пост по материлам статьи 

Цитата о распределенных вычислениях

Цитата к первой главе третьего издания руководства о Hadoop.

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

MongoDB: подсчет количества уникальных значений параметра в коллекции

Появилась необходимость подсчитать количество уникальных значений параметра в коллекции. Сначала был испробован distinct, который успешно справился с формированием отсортированного уникального списка значений, но вот организовать подсчет для этого списка в одном запросе не удалось. Успех был получен при использовании group и reduce:

db.my_collection.group({

    key: {"field": true}, 

    initial: {sum: 0}, 

    reduce: function(doc, prev) { prev.sum += 1}

})

Или как вариант:

db.$cmd.findOne({

    group: { 

        ns: "my_collection", 

        cond: {}, 

        key: {"field": true}, 

        initial: {sum: 0}, 

        $reduce: function(doc, prev) { prev.sum += 1}

        }

})

Nginx + haproxy + apache ?

Есть задача — построить отказоустойчивый web-кластер высокой доступности.

  • frontend — nginx
  • loadbalancer — haproxy
  • backend — apache

Дано: 2 сервера nginx, 2 сервера haproxy, 4 сервера apache

Но возникает академический интерес в расположении данных элементов в цепочку…

nginx — haproxy — apache ?
round-robin на входе, кеш до haproxy, haproxy распределяет нагрузку по апачам
Смущает round-robin на входе, в остальном вроде идет равномерное распределение нагрузки по апачам

haproxy — nginx — apache ?
Плохие стороны round-robin в рамках haproxy можно заменить keepalived (?)
Балансировка между апачами выглядит не так хорошо как с haproxy

Собственно приглашаю в комменты для обсуждения.

Обзор Kanban досок

Kanban

Наверняка многие из вас уже сталкивались с манифестом Agile методологии, кому-то идея нравится, а для кого-то это хаос. На мой взгляд самым простым и эффективным методом планирования работы является kanban доска, но в случае распределенной команды её эффективное использование крайне затруднительно. Поскольку greenhopper 6.0 от Atlassian, в котором можно будет создавать мультипроектные канбан доски, будет зарелизен не раньше лета, то я решил пройтись по ресурсам, которые доступны уже сейчас. По функционалу они близки друг к другу, опишу совсем кратенько:

  1. Agilezen
    Бесплатный аккаунт очень урезан по возможностям, есть flow-диаграммы, система обмена сообщения для совместной работы.
  2. Kanbantool
    Можно бесплатно использовать одну доску на двух пользователей, есть API, хороший функционал, поддержка touch интерфейсов.
  3. Lean Kit Kanban
    Бесплатно предоставляется 1 доска на 5 пользователей, есть API, возможность import/export, хорошо реализована совместная работа, уведомления, статистика, диаграммы.
  4. Bananascrum
    Бесплатно предоставляется 1 проект на 3 пользователей. Приложение не понравилось в использовании, а в остальном тот же функционал как и у других.
  5. Swift
    Бесплатное бета-тестирование. Крайне богатый функционал и приятная реализация.
  6. flow.io
    Бесплатно предоставляется 1 пользователь на 1 проект, есть api, ведутся часовые снапшоты проектов для отслеживания истории развития проекта. Приятна в использовании.
  7. Hansoft
    Большая и крайне вкусная система, есть триал на 2х пользователей. Функционал лучше разглядывать на сайте, его не описать =)
  8. Kanbanery
    Бесплатно предоставляется 1 доска на 2 пользователя. Полноценно посмотреть не дошли руки.
  9. smartQ
    Есть триал. Красивая реализаци, можно погрузиться в демку.
  10. TargetProcess
    Есть возмжоность интеграции с JIRA. Очень богатый функционал, лучше перейти на их сайт и посмотреть самим =)
  11. VersionOne
    Бесплатно 10 пользователей. Есть возможность интеграции с JIRA. Но как-то не понравилась на тему удобства использования.
  12. Kanbanize
    Приятен в использовании, полностью бесплатен (может по этой причине и приятен=)
  13. Agilo
    Вполне продуманный интерфейс, интересное лицензирование — можно скачать, а можно воспользоваться hosted версией. Бесплатна.
  14. Xplanner-plus
    Бесплатный opensource проект.
  15. Scrumdesk
    Бесплатен для 5 пользователей. На время написания заметки сайт лежал, так что потом что-нибудь напишу.
  16. Seenowdo
    Интересный бесплатный проект, но вот тяжелое и тормозное флеш приложение расстраивает, если вас это не останавливает, то стоит попробовать.
  17. Scrumy
    Бесплатный, но крайне странный.
  18. Ontime
    1 бесплатный пользователь. Толком посмотреть не удалось.
  19. Spaaze
    Это конечно не kanban доска, но по сути её можно использовать вообще для любых целей.

Авторизация в MongoDB

По умолчанию, MongoDB не использует какие-либо способы авторизации для доступа к базе данных.
Сами разработчики MongoDB объясняют это тем, что всю логику должно содержать в себе приложение, а база должна делать то, для чего она лучше всего и предназначена — хранение и управление данными.

В SQL базах вы можете иметь множество пользователей, групп и схем для более тонкой настройки прав доступа к данным. Но если не рассматривать MongoDB только со стороны философии, которую они пропагандируют, то можно найти прекрасный механизм авторизации.

Хотите добавить пользователей к своей базе на MongoDB ?

MongoDB позволяет управлять пользователями на уровне базы, но правда только в «read/write» или «readonly» режимах.

Создание пользователя с правами «read/write»:

$ ./mongo
> use mydatabase
> db.addUser(«admin», «Sup3rG00dP@azzword»)

Создание пользователя с правами «readonly»:

> db.addUser(«web», «prettyGoodPass», true)

Параметр true как раз и задает readonly права для создаваемого пользователя.

Смена пароля:
Для смены пароля необходимо еще раз вызвать addUser

> db.addUser(«web», «wayGooderPass», true)

Удаление пользователя:
Для удаления пользователя вам необходимо удалить соответсвующий документ в system.users коллекции

> db.system.users.remove({«user» : «web»});

Настроить монго для использования авторизации:
Если вы хотите полностью закрыть неавторизованный доступ, то требуется изменение конфигурации MongoDB.
auth = true
После этих изменений требуется перезапуск демона.
Если вы попытаетесь получить доступ с данными несуществующего пользователя, то вы получите ошибку вида:

error: { “$err” : “unauthorized for db [mydatabase] lock type: -1 ” }

Также readonly пользователь при попытке записи получит ошибку:

unauthorized

Адекватны ли пользователи вашей системы?

История: Как-то давно писал статью на Хабре, но что-то не взлетела, решил вот утащить её в свой блог, может вторая жизнь породит новые веяния в умах =)

Наверняка многие использовали для записи сессий командной строки программу script.
А кто-нибудь задавался вопросом, а можно ли использовать её в рамках повышения безопасности/мониторинга/проверки адекватности пользователей системы?
Любопытства ради решил прикрутить script ко всем пользователям системы и посмотреть, что из этого выйдет…

 

#!/bin/sh
if [ "$TERM" != "" ]; then
DATE=`date +%F.%H.%M`
FOLDER="/tmp/"
exec script -q -t $FOLDER$USER.$DATE 2> $FOLDER$USER.$DATE.time
else
/bin/sh $*
fi

Добавляем такой скрипт в /etc/profile (в gentoo сохранил это в файл bash.sh и поместил его в директорию /etc/profile.d/).

Можно проверять работоспособность, заходя по SSH или любым другим способом.

В /tmp должны появиться файлы вида test.2010-03-25.20.01 и test.2010-03-25.20.01.time.
Файл c .time содержит в себе всю информацию по таймингу сессии.

Если файлы создались, дабы проверить плоды, запускаем:

scriptreplay test.2010-03-25.20.01.time test.2010-03-25.20.01

и наслаждаемся просмотром.

Хочу сразу сказать недоработки:
1 Если подключаться ssh user@host /bin/bash -i — то ничего не логируется =(

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

Так же можно создать отдельный каталог вместо /tmp, например /opt/sessions и задать права:

chmod 733 /opt/sessions

Дабы все сессии могли писать, но юзеры не могли сделать листинг этой дирекории.

Оригинал

Экстремальное парное программирование

Из всех практик экстремального программирования, наибольшее сопротивление встречает парное программирование. Некоторые любят его, а некоторые ненавидят.

Болтливый кодер

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

Что вы думаете? Принадлежит ли это к этому домену или нет? Много ли выполняет этот класс?

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

Герой в наушниках

Другие же больше любят работать в одиночку, они предпочитают воткнуть наушники и погрузиться в свой отрешенный от офисной суеты мир. Они не задают вопросов и стараются войти в нирвану программирования 🙂 Они, как правило, не большие фанаты парного программирования. Они не будут жаловаться, если посадить с ними кого-то рядом, хоть это и будет их раздражать. Но если посадить с ними кого-то с меньшими навыками, то они воспримут это как возможность поупражняться и будут более открыты для общения. Они могут упорно набивать код, пока не начинают понимать, что за ними уже минут 30 наблюдает их партнер. В таком случае они передают эстафету с видом «ну пакажи на что ты способен». Вы можете воспринять это как покровительство, но со временем «герои» осознают, что и они могут получить плюсы, которые помогут им на их пути в нирвану.

Трололокодер

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

Техники парного программирования:

«Пинг-понг» программирование

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

Слияние пары и саморазвитие

Данная техника подразумевает обмен знаниями между более и менее квалифицированными программистами. Данная техника также характеризует «героя в наушниках». Некоторые люди не понимают преимуществ парного программмирования, но скажите им, что это для обмена опытом и они примут его. С течением времени они даже начнут наслаждаться им. Но, конечно, они всегда могут вернуться к своим наушникам =)

Удаленное парное программирование

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

Ротация пар

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

Оригинал

Неоднозначные «приветствия мира»

Всё привыкли, что программисты — уравновешенные, спокойные, логически мыслящие люди..
Но по примерам кода, которые представлены ниже, так и хочется назвать некоторых из них — АДСКИМИ ПСИХОПАТАМИ !! +) Ну и конечно же в нашем обществе существует такой стереотип в основном о программистах на С..

Вынос мозга раз:

    #define _________ }
#define ________ putchar
#define _______ main
#define _(a) ________(a);
#define ______ _______(){
#define __ ______ _(0x48)_(0x65)_(0x6C)_(0x6C)
#define ___ _(0x6F)_(0x2C)_(0x20)_(0x77)_(0x6F)
#define ____ _(0x72)_(0x6C)_(0x64)_(0x21)
#define _____ __ ___ ____ _________
#include<stdio.h>

Дваз:

#include<stdio.h>
main(){
int x=0,y[14],*z=&amp;y;*(z++)=0x48;*(z++)=y[x++]+0x1D;
*(z++)=y[x++]+0x07;*(z++)=y[x++]+0x00;*(z++)=y[x++]+0x03;
*(z++)=y[x++]-0x43;*(z++)=y[x++]-0x0C;*(z++)=y[x++]+0x57;
*(z++)=y[x++]-0x08;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x06;
*(z++)=y[x++]-0x08;*(z++)=y[x++]-0x43;*(z++)=y[x]-0x21;
x=*(--z);while(y[x]!=NULL)putchar(y[x++]);
}

Триз:

#include<stdio.h>
#define __(a) goto a;
#define ___(a) putchar(a);
#define _(a,b) ___(a) __(b);
main()
{ _:__(t)a:_('r',g)b:_('$',p)
c:_('l',f)d:_(' ',s)e:_('a',s)
f:_('o',q)g:_('l',h)h:_('d',n)
i:_('e',w)j:_('e',x)k:_('n',z)
l:_('H',l)m:_('X',i)n:_('!',k)
o:_('z',q)p:_('q',b)q:_(',',d)
r:_('i',l)s:_('w',v)t:_('H',j)
u:_('a',a)v:_('o',a)w:_(')',k)
x:_('l',c)y:_('t',g)z:___(0x0)}

Четырез:

int n[]={0x48,
0x65,0x6C,0x6C,
0x6F,0x2C,0x20,
0x77,0x6F,0x72,
0x6C,0x64,0x21,
0x0A,0x00},*m=n;
main(n){putchar
(*m)!=''?main
(m++):exit(n++);}
 

Пздез:

main(){int i,n[]={(((1<<1)<<(1<<1)<<(1<<
1)<<(1<<(1>>1)))+((1<<1)<<(1<<1))), (((1
<<1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<<(
1<<1)<<(1<<1))+((1<<1)<<(1<<(1>>1)))+ (1
<<(1>>1))),(((1<<1)<<(1<<1)<<(1<<1)<< (1
<<1))-((1<<1)<<(1<<1)<<(1<<(1>>1)))- ((1
<<1)<<(1<<(1>>1)))),(((1<<1)<<(1<<1)<<(1
<<1)<<(1<<1))-((1<<1)<<(1<<1)<<(1<<(1>>1
)))-((1<<1)<<(1<<(1>>1)))),(((1<<1)<< (1
<<1)<<(1<<1)<<(1<<1))-((1<<1)<<(1<<1)<<(
1<<(1>>1)))-(1<<(1>>1))),(((1<<1)<<(1<<1
)<<(1<<1))+((1<<1)<<(1<<1)<<(1<<(1>>1)))
-((1<<1)<<(1<<(1>>1)))),((1<<1)<< (1<<1)
<<(1<<1)),(((1<<1)<<(1<<1)<<(1<<1)<<(1<<
1))-((1<<1)<<(1<<1))-(1<<(1>>1))),(((1<<
1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<< (1
<<1)<<(1<<(1>>1)))-(1<<(1>>1))), (((1<<1
)<<(1<<1)<<(1<<1)<<(1<<1))- ((1<<1)<< (1
<<1)<<(1<<(1>>1)))+(1<<1)), (((1<<1)<< (
1<<1)<<(1<<1)<< (1<<1))-((1<<1)<< (1<<1)
<<(1<<(1>>1)))-((1<<1) <<(1<< (1>>1)))),
(((1<<1)<< (1<<1)<<(1<<1)<< (1<<1))- ((1
<<1)<<(1<<1)<<(1<<1))+((1<<1)<< (1<<(1>>
1)))), (((1<<1)<<(1<<1) <<(1<<1))+(1<<(1
>>1))),(((1<<1)<<(1<<1))+((1<<1)<< (1<<(
1>>1))) + (1<< (1>>1)))}; for(i=(1>>1);i
<(((1<<1) <<(1<<1))+((1 <<1)<< (1<<(1>>1
))) + (1<<1)); i++) printf("%c",n[i]); }
 

Как из плюсиков и минусов вырисовываются слова??

#include <stdio.h>
#define _(_) putchar(_);
int main(void){int i = 0;_(
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++i)_(++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++i)_(++++++++++++++
i)_(--++i)_(++++++i)_(------
----------------------------
----------------------------
----------------------------
----------------------------
----------------i)_(--------
----------------i)_(++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++++
++++++++++++++++++++++++++i)
_(----------------i)_(++++++
i)_(------------i)_(--------
--------i)_(----------------
----------------------------
----------------------------
----------------------------
----------------------------
------i)_(------------------
----------------------------
i)return i;}

P.S. может у кого-то такой стиль используется на предприятии в качестве основного стиля форматирования и обфускации? o_O