четверг, 27 января 2011 г.

Инструменты для работы с людьми

Известные люди в среде управления IT-проектами, Александр Орлов и Вячеслав Панкратов опубликовали бесплатную подборку видео-уроков на тему "Инструменты для работы с людьми" . Уроки короткие (несколько минут), ёмкие, интересные и с улыбкой. Всего 9 уроков. Как мне кажется, интересны они будут не только менеджерам, но и всем думающим людям.

Темы уроков :
1. Четыре причины, почему люди чего-то не делают
2. Матрица интереса и компетентности
3. Матрица осознанности и компетентности
4. Ситуационное управление
5. Конструктивность и конфронтация
6. Оценка идей и людей
7. Доверие и прозрачность
8. Результат и заметность
9. Матрица Эйзенхауэра

Зарегистрироваться и скачать можно здесь : http://www.stratoplan.ru/manager-tools.htm

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

Модель зрелости REST сервисов Леонарда Ричардсона (Richardson Maturity Model)

Уровень 0

Сервисы имеют единственный URI, который использует единственный http-метод (как правило, метод POST).Примерами таких сервисов могут служить большинство веб-сервисов - они используют единственный URI для идентификации точки входа и HTTP POST для передачи SOAP-пакета с данными. Службы XML-RPC и POX(Plain Old XML) используют похожие вызовы, при которых по одному URI передаётся XML, как часть http-запроса.

Уровень 1 (Resources(Ресурсы))

Такие сервисы используют несклько URI, но единственный http-метод. Разница между L1 и L0, заключается в том, что L1 выставляет много логических ресурсов, а сервис уровня L0 объединяет все взаимодействия через единственный (большой и сложный) ресурс. В сервисах уровня L1, имена операций и параметров находятся в самом URI и передаются удалённому сервису, как правило через HTTP GET.

Уровень 2 (HTTP-verbs(http-методы/глаголы))

Сервивсы этого уровня имеют много URI-адресуемых ресурсов и используют несколько http-методов для каждого ресурса. Это, как правило CRUD(Create Read Update Delete)-сервисы, где состояние ресурса представляет бизнес-сущность, которой можно управлять через сеть.

Уровень 3 (Hypermedia Controls)
(Управление гиперсодержанием (? ничего лучшего в голову не пришло при переводе)))

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

Пример запроса (уровень 3):

POST /slots/1234 HTTP/1.1
[various other headers]

<appointmentRequest>
  <patient id = "jsmith"/>
</appointmentRequest>


и ответа (уровень 3):

HTTP/1.1 201 Created
Location: http://royalhope.nhs.uk/slots/1234/appointment
[various headers]

<appointment>
  <slot id = "1234" doctor = "mjones" start = "1400" end = "1450"/>
  <patient id = "jsmith"/>
  <link rel = "/linkrels/appointment/cancel"
        uri = "/slots/1234/appointment"/>
  <link rel = "/linkrels/appointment/addTest"
        uri = "/slots/1234/appointment/tests"/>
  <link rel = "self"
        uri = "/slots/1234/appointment"/>
  <link rel = "/linkrels/appointment/changeTime"
        uri = "/doctors/mjones/slots?date=20100104@status=open"/>
  <link rel = "/linkrels/appointment/updateContactInfo"
        uri = "/patients/jsmith/contactInfo"/>
  <link rel = "/linkrels/help"
        uri = "/help/appointment"/>
</appointment>




Ссылки
http://www.crummy.com/writing/speaking/2008-QCon/act3.html
http://martinfowler.com/articles/richardsonMaturityModel.html

четверг, 13 января 2011 г.

Русская буква «И» при формировании строки из массива байт


Дано:

При получении массива байт извне (например, через jni-буфер) необходимо преобразовать его в строку Java, с русскими буквами.  

В чём сложность:
(отличное описание взято отсюда http://www.skipy.ru/technics/encodings.html):

Символ "И" кодируется в UTF-8 последовательностью из двух байтов: 0xD0,0x98. Соответственно, при чтении в кодировке windows-1251 каждый из этих байтов декодируется по схеме данной кодировке. Так вот, я обнаружил следующее – код 0x98 не определен в наборе символов windows-1251 и, соответственно, в схеме этой кодировки. Вот схема кодировки cp1251, взятая с сайта Microsoft, а вот ее описание (взято отсюда). Как вы можете видеть, код 0x98 описан как UNDEFINED.

Проблема и решение:

Допустим откуда-то извне к нам попал массив байт, с неизвестной кодировкой. И с этим массивом надо проделать некоторые преобразования, то возможен хитрый ньюанс. Если на входе кодировка UTF-8, а в массиве есть русская буква И, то при попытке в java-коде создать строку с кодировкой windows-1251, мы получим «?»(он же - неопределённый байт) в созданной строке. При дальнейшем преобразовании в байты, этот символ просто потеряется (зачем нужны такие преобразования, я тут рассматривать не буду, но иногда такие вещи случаются :-)).

Немного кода :

// получаем правильную последовательность байт (то, что пришло нам извне)
byte[] bytes = «И-диотизм».getBytes("UTF-8");

// Создаём строку с кодировкой по умолчанию
// Напечатает «Каракули=Р?-диотизм», где видно, что один символ «?»
System.out.println("Каракули=" + new String(bytes, "Cp1251"));
System.out.println("Каракули=" + new String(bytes));  // аналогично

// Дальнейшее преобразование и потеря информации
String s1251_x = new String(bytes);
 String xx = new String(s1251_x.getBytes(), "UTF-8"); // даже в изначально правильной кодировке
// Выведет «xx=??-диотизм,len=10»
 System.out.println("xx=" + xx + ",len=" + xx.getBytes().length);

Решение :

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

// Если сразу сделать так
String sUtf8 = new String(bytes, "UTF-8");
// то и дальнейшие преобразования не потеряют информацию на входе
// Напечатает «sUtf8=И-диотизм,len=17»
System.out.println("sUtf8=" + sUtf8 + ",len=" + bytes.length);
 String s1251_2 = new String(sUtf8.getBytes(), "Cp1251");
// Напечатает «s1251_2=И-диотизм»
 System.out.println("s1251_2=" + s1251_2);

P.S.: Я эти заметки пишу для себя, и для конкретной ситуации, которая случилась в нашем коде. О глобальном подходе к кодированию/декодированию очень понятно и хорошо написано тут : http://www.skipy.ru/technics/encodings.html