Сертификация Nokia Qt: новый уровень



Сегодня пришло письмо из Нокии о том, что скоро будет доступен новый уровень сертификации для Qt-разработчиков — Nokia Certified Qt Specialist.

Напомню, что программа сертификации по Qt была впервые представлена в октябре 2009 года, первый и единственный ее уровень назывался Nokia Certified Qt Developer, а экзамен — Qt Essentials, то бишь основы Qt. Могу сказать, что для практикующих Qt-программистов экзамен этот достаточно легкий, многие (в т.ч. ваш покорный слуга) проходят его, не готовясь практически вообще.

Новый уровень сертификации (Нокия называет уровни certification schemes) будет представлен на конференции Qt Developer Days 2010, которая скоро пройдет в Мюнхене и Сан-Франциско. Посетителям конференции будет предоставлена возможность попробовать сдать бета-версии новых экзаменов бесплатно.

Почему «экзаменов», а не «экзамена»? Потому что новых экзаменов сразу два: Advanced Widget UI и Qualified in C++ with Qt. Оба они являются продвинутыми экзаменами, в противовес старому обычному Qt Essentials.

Экзамен Advanced Widget UI


Разработка UI с помощью виджетов является одной из старейших фич Qt. Также это одна из наиболее часто запрашиваемых тем-кандидатов для продвинутых экзаменов. Qt Essentials покрывает лишь основы, которые надо знать для того, чтобы начать разработку GUI с помощью виджетов. Более сложные, но необходимые для сколь-нибудь сложных программ темы, такие как Model/View Framework, кастомные виждеты и многопоточность, сейчас включены в этот новый экзамен.

Рекомендации от составителей:
Для успешного прохождения экзамена вам следует иметь хотя бы полтора года опыта фуллтайм-разработки с Qt, включая разработку GUI, логику сложных и мультипоточных программных систем с кастомными UI-элементами и стилями.

Учебный план экзамена состоит из следующих тем:
  • Model/View
  • Multithreaded programming in Qt
  • Rich text processing
  • Manage Qt Projects (Develop / Unit Test / Port / License)
  • Creating plugins
  • Drag/Drop and Clipboard access
  • Custom Widgets
  • Styling widgets
  • Making Applications scriptable
  • Writing code for efficient Internationalization
  • Using the Undo Framework
С полным списком, состоящим из 71 подтемы, можно ознакомиться здесь: Advanced Widget UI Curriculum.

Экзамен Qualified in C++ with Qt


Qt известна своим достаточно низким порогом вхождения в том плане, что не надо быть С++-гуру, чтобы начать писать Qt-приложения. Qt Essentials охватывал основные аспекты С++/Qt-разработки, позволяющие делать относительно простые программы. Экзамен Qualified in C++ with Qt призван выявить наличие более продвинутых знаний в C++/Qt, которые нужны для разработки сложных программ.

Рекомендации от составителей:
Для успешного прохождения экзамена вам следует иметь хотя бы три года опыта парт-тайм разработки на C++ плюс один год разработки с использованием Qt.

Учебный план экзамена состоит всего из четырех тем:
  • Types, Declarations and Definitions
  • Classes
  • Inheritance and Polymorphism
  • Miscellaneous Topics

Более информативных список с подтемами лежит тут: Qualified in C++ with Qt Curriculum.

При сдаче каждого из экзаменов вам будет предложено ответить на 30 вопросов за 60 минут. Плюс дополнительное время на комментарии и, наверняка, еще добавят хотя бы по 15 минут тем, для кого английский язык не родной.

Дополнительные ссылки по теме:
«А зачем мне эта сертификация вообще нужна?»
Qt Certification Start Page
Топик про Qt-сертификацию на форуме prog.org.ru, личный опыт сдававших экзамены.

Комфортное рабочее окружение на примере awesome wm (взгляд изнутри)

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

Почему тайлинг?


Тайлинг — очень удобный способ управления рабочим пространством. Основными достоинствами являются:

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

Минусы, конечно же, тоже есть, но они больше относятся к начальным этапам:
  • нужно потратить определенное количество времени для приведения оконного менеджера к комфортному для себя виду
  • не подходит для любителей грызунов.

Из множества существующих тайловых оконных менеджеров я остановился на awesome wm, как наиболее оптимальном для меня варианте. Однако настроить исключительно внешний вид — это всего лишь полдела. Стоит отметить, что awesome это всего лишь оконный менеджер, и если его не использовать в качестве оконного менеджера в kde/gnome/etc, то рабочее окружение придется настраивать самостоятельно. Однако овчинка стоит выделки.


Читать дальше →

Коммуникационные привязки в Windows Communication Framework (WCF)

Введение


Привязки описывают соглашения между клиентом и сервером о порядке передачи данных по сети. В привязке задается способ транспортировки, кодирование и протоколы, участвующие в коммуникации. WCF с помощью привязок инкапсулирует конфигурацию в различных сценариях коммуникации. Для наиболее распространенных сценариев – Web-служб, служб REST/POX и приложений на основе очередей – имеются уже готовые привязки. Например, привязка basicHttpBinding предназназначена для работы с Web-службами, созданными в ASP.NET или совместимыми со спецификацией WSI Basic Profile 1.1. Привязки ws2007HttpBinding и wsHttpBinding похожи на basicHttpBinding, но поддерживают больше возможностей, в частности надежную доставку и транзакции, а также основаны на более современных стандартах, таких, как WSAddressing. В таблице 1 перечислены 12 привязок, применяемых в разных сценариях коммуникации.
Читать дальше →

Избавление от KAPTCHA, раз и на всегда

Фразы «введите символы с картинки» начали всех уже не просто доставать, а их не читабельность, ну просто выводит из себя. Примерно с полгода назад я задумался а как можно обойтись без нее и все оказалось гораздо проще чем можно представить. Ну для начала посмотрим в историю, от куда появились «каптчи» и зачем — ответ очевиден, для того, что-бы избавиться от роботов разного уровня. Исходя из данного можно подумать теперь над другим: ботов пишут для сайтов типа форумы, блоги, т.е. тех куда можно в свободной и бесплатной форме запостить рекламное сообщение. Посмотрим на это со стороны «бото-писца», как пишут ботов?:


Читать дальше →

Программное обеспечение для работы над диссертацией

В настоящей статье речь пойдет о программном обеспечении, которое оказывает неоценимую помощь при работе над диссертацией. Равным образом оно пригодится и тем, кто пишет курсовую, диплом или магистерскую. Основное внимание будет уделено не специальному софту (для проведения расчетов, прогнозирования и пр.), а программному обеспечению, служащему для решения трех общих задач:
структурирование данных, собранных из различных источников;
работа непосредственно с текстом диссертации;
работа со сносками и списком литературы,
что в той или иной мере пригодно для ученых всех специальностей.
Читать дальше →

Совместное использование Unity и ASP.NET MVC

В этой статье я опишу, как использовать библиотеку Microsoft Unity в приложениях ASP.NET MVC. А также, какие преимущества от этого можно получить, в частности для написания unit-тестов.

Как известно, Unity представляет собой реализацию паттерна Dependency Injection (DI). Кратко опишу, что собой представляет DI(“ внедрение зависимостей”). Представим, что некий объект использует в своей работе какой-то сервис. Ссылка на сервис хранится в приватном поле объекта. Для того, что бы объект не был жестко связан с сервисом (coupling), мы можем применить «внедрение зависимостей». DI представляет механизм, позволяющий в момент создания объекта извне инициализировать ссылку на сервис. Как правило, это делается через публичное свойство или параметризованный конструктор.

И так, для начала рассмотрим, как выглядит простое MVC приложение, без использования Unity. Предположим, что у нас есть контроллер, передающий во view список пользователей. Контроллер обращается к статическому методу класса DataHelper, для получения списка пользователей. DataHelper, в свою очередь, обращается к базе данных.

<code>public class DataHelper
{
  public static List<User> GetAllUsers()
  {
    //connect to DB and fetch list of users
  }      
}

public class UserController
{
  public ActionResult ShowAll()
  {
    return View(DataHelper.GetAllUsers().ToList());
  }
}

* This source code was highlighted with Source Code Highlighter.


В данной реализации, мы видим сильную “связанность” классов UserController и DataHelper.
И как следствие этого, есть проблема с тестированием метода ShowAll. Мы не можем протестировать этот метод, без вызова метода GetAllUsers и соответственно обращения к базе данных.

Теперь, рассмотрим вариант с использованием Unity. Первое, что мы сделаем – избавимся от статического метода в DataHelper и выделим интерфейс. А заодно переименуем класс DataHelper в DataService.
public interface IDataService
{
  List<User> GetAllUsers();
}

public class DataService : IDataService
{
  public List<User> GetAllUsers()
  {
    //connect to DB and fetch list of users
  }      
}

* This source code was highlighted with Source Code Highlighter.


Внесем изменения в реализацию контроллера: добавим публичное свойство DataService, в котором будет храниться ссылка на экземпляр IDataService, и пометим это свойство атрибутом Dependency.
[Dependency]
public IDataService DataService { get; set; }
public class UserController
{
  public ActionResult ShowAll()
  {
    return View(DataService.GetAllUsers().ToList());
  }
}

* This source code was highlighted with Source Code Highlighter.


Теперь осталось настроить собственно сам Unity. Мы сделаем это в модуле Global.ascx.
protected void Application_Start()
{
  …
  InitContainer();
}    

private static UnityContainer _container;
private static void InitContainer()
{
  if (_container == null)
    _container = new UnityContainer();

  IControllerFactory controllerFactory = new UnityControllerFactory(_container);
  ControllerBuilder.Current.SetControllerFactory(controllerFactory);

  _container.RegisterType<IDataService, DataService>(new ContainerControlledLifetimeManager());
}

* This source code was highlighted with Source Code Highlighter.


Обратите внимание, что в методе InitContainer мы регистрируем тип и его реализацию, который Unity будет внедрять, основываясь на атрибуте Dependency. При этом в качестве параметра метода RegisterType передается экземпляр ContainerControlledLifetimeManager. Это значит, что каждый раз, при вызове метода контейнера Resolve, будет возвращаться один и тот же экземпляр DataService.

И последнее, что нам осталось сделать, это реализовать свою собственную фабрику контроллеров UnityControllerFactory. Эта фабрика будет возвращать экземпляр котроллера UserController уже проинициализированный экземпляром DataService.
public class UnityControllerFactory : DefaultControllerFactory
{
  IUnityContainer _container;

  public UnityControllerFactory(IUnityContainer container)
  {
    _container = container;
  }

  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
  {
    if (controllerType == null)
      throw new ArgumentNullException("controllerType");

    if (!typeof(IController).IsAssignableFrom(controllerType))
      throw new ArgumentException(string.Format(
        "Type requested is not a controller: {0}", controllerType.Name),
        "controllerType");

    return _container.Resolve(controllerType) as IController;
  }
}

* This source code was highlighted with Source Code Highlighter.


На этом этапе мы реализовали использование Unity в приложении MVC. Теперь можем написать unit test метода ShowAll класса UserController. Сначала создаем mock класс:
public class TestDataService : IDataService
{
  public List<User> GetAllUsers()
  {
    return new List<User>
      {
        new User
           {
              FirstName = "firstname",
              LastName = "lastname",
              Age = "34"
            }, 
        new User
           {
               FirstName = "firstname1",
               LastName = "lastname1",
               Age = "31"
            }
      }
  }
}

* This source code was highlighted with Source Code Highlighter.


И собственно сам тест:
[TestMethod]
public void ShowAllTest
{
  var container = new UnityContainer();
  container.RegistryType<IDataService, TestDataService>();

  var userController = container.Resolve<UserController>();
  ViewResult result = controller.ShowAll() as ViewResult;
  
  var list = result.ViewData.Model as IEnumerable<User>
  Assert.AreEqual(2, list.Count());
}

* This source code was highlighted with Source Code Highlighter.


Теперь проверяется код только метода ShowAll, и он не зависит от класса DataService и тем более от базы данных.

В заключении хочу отметить два момента. В production мы можем настраивать контейнер Unity декларативно, с использованием конфигурационного файла. Т.о., для перехода на тестовый environment, нам не надо изменять код, достаточно поменять конфигурационный файл. И второе, «внедрение зависимостей» мы можем производить не только через публичное свойство, но и через параметризованный конструктор. И в том, и в другом случае такие члены должны помечаться атрибутом Dependency.

О чём говорит apache benchmark

Когда я первый раз столкнулся с задачей оптимизации скорости работы сайта, я начал рыскать по просторам интернета, чтобы получить хоть какое-то представление о том, как эта самая оптимизация делается. Именно тогда я в первый раз услышал об утилите «apache benchmark», которая как сказано в описании официального сайта apache «главным образом показывает, как много запросов способен выполнить ваш сервер».

Прочитав документацию, я решил опробовать утилиту в действии, а в качестве подопытного использовать сайт самих разработчиков apache. После того как я прописал в консоль «ab -c10 -n100 httpd.apache.org/», мне сообщили что «httpd.apache.org» бенчмаркетится (benchmarkering), что если верить словарю переводится как «тестируется». Также мне посоветовали быть терпеливым, что я собственно и сделал. Спустя некоторое время, утилита выдала информацию о результатах своего труда. Должен признать, что увидев данную таблицу впервые, я не понял ровным счетом ничего, и вынести для себя какую-то полезную информацию было достаточно тяжело. Потратив некоторое время я, конечно, во всем разобрался, и сейчас хочу поделиться тем, как я понимаю то, о чем нам говорит «apache benchmark».

Итак, результаты тестирования были следующими:



Вначале все предельно понятно:

Server Software: Apache/2.3.8 — установлен сервер Apache (вот было бы весело если бы было по другому) версии 2.3.8.

Server Hostname: httpd.apache.org — имя сервера хостинга httpd.apache.org.

Server Port: 80 — при тестировании использовался 80-й порт.

Document Path: / — путь к документу. В нашем случае — основная директория.

Document Length: 13666 bytes — размер документа — 13,6Кб. Причем, это размер не учитывающий встроенные элементы, например, изображения. Сохранив страницу на локальный компьютер, можно увидеть, что на странице размещены два изображения общим размером 18Кб, а вот сам html файл страницы весит приблизительно 14Кб.

Concurrency Level: 10 — если перевести, то это будет звучать как «уровень параллелизма». О чем-нибудь говорит? Когда я увидел это впервые, мне это не говорило ни о чём. Немного поразмыслив, я предположил, что это количество одновременных запросов, которое выполнял сервер в процессе тестирования. Проделав еще несколько тестов, изменяя опцию "-cN", я понял что оказался прав.

Time taken for tests: 28.252 seconds — тестирование выполнялось в течении 28-и с лишним секунд.

Complete requests: 100 — было выполнено 100 запросов.

Failed requests: 0 — неудачно выполненных запросов было 0.

Write errors: 0 — ошибок в журнал записано не было.

Total transferred: 1404503 bytes — общее количество информации, которое было получено от сайта httpd.apache.org.

HTML transferred: 1372882 bytes — похоже, что сюда не включены изображения, флеш-анимации и прочее. Если мы поделим «HTML transferred» на «Document Length», то получим 100 с копейками, что соответствует значению выполненных запросов «Complete requests».

Requests per second: 3.54 [#/sec] (mean) — количество запросов за секунду. Это среднее значение — результат деления «Complete requests» на «Time taken for tests».

Time per request: 2825.237 [ms] (mean) — время, в течении которого выполнялись 10 параллельных запросов.

Time per request: 282.524 [ms] (mean, across all concurrent requests) — время, в течении которого выполнялся один запрос. То есть значение «Time per request», разделённое на «Concurrency Level».

Transfer rate: 48.55 [Kbytes/sec] received — скорость, с которой apache benchmark получал информацию с тестируемого сервера.

Connection Times (ms) — таблица со временем соединения в миллисекундах. Здесь мы имеем таблицу с четырьмя строчками и четырьмя столбцами:
Строка Connect: — время, которое потратила утилита на соединение с сервером.
Строка Processing: — время выполнения запроса.
Строка Waiting: — время простоя запроса. То есть время, которое запрос ждал своей очереди для выполнения.
Строка Total: — общее время по строкам.

Столбец min — минимальное время.
Столбец mean[±sd] — по этому столбцу, к сожалению, информации не имею. Если, у кого-то есть сведения по нему, пожалуйста, поделитесь.
Cтолбец median — среднее время.
Стобец max — максимальное время.

Исходя из результатов тестирования видно, что самый быстрый запрос был выполнен за 1.194 секунды, а самый медленный за 10.614 секунд.

Percentage of the requests served within a certain time (ms) — доля запросов, выполненных в определенное время. То есть 80 процентов всех запросов выполнились в течении 2-х с небольшим секунд. А самый долгий запрос выполнялся 10 с лишним секунд.

Итоги: На мой взгляд особого внимания заслуживают: Requests per second, а также min и max значения таблицы Connection Times (ms). Опираясь на эти данные, мы можем сказать, что сайт «httpd.apache.org» при нагрузке в 10 одновременно зашедших на сайт посетителей, загрузит страницу в лучшем случае за 1.194 секунды, в худшем за 10.614 секунд. Конечно, для полной оценки работы сервера нужно проводить несколько тестов, изменяя опции "-cN" и "-nN". Таким образом можно увидеть, как изменяются показатели сервера в зависимости от нагрузки.

Простая шифровка методами Javascript

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

А задание в данных условиях самое что ни на есть гадкое, а именно обеспечить контент, закрытый от посторонних глаз и доступный исключительно избранным. Казалось бы ну никак не сохранить от этого юзера данные, они ведь ему передаются в самом что ни на есть открытом виде и никаких тут тебе «на стороне сервера». Но мы то знаем, что есть такая штука, как шифрование и средствами javascript и dhtml его обеспечить очень даже можно.


Читать дальше →

Язык программирования не выучить за месяц

Выучить один из основных языков программирования за месяц невозможно. Опытный программист решит поставленную задачу с помощью незнакомого языка в короткие сроки, если задача типовая, а кардинально непривычных конструкций нет. Грубо говоря, любой может за день на любом языке написать “Hello, World!” на любимом языке, но не следует путать это со знанием. В вузе можно некоторое время учиться для галочки по методу “зазубрил, сдал, забыл”, а в резюме при поступлении на первую работу указать “Владею C, C++, Python, Java, Javascript, ASM, PHP, Ruby, SQL” (потратил девять месяцев и стал универсалом), чем позабавить принимающую сторону. В жизни после вуза требования к уровню знаний специалиста другие.

Так после чего можно сказать, что выучил?

Читать дальше →

О проблеме развития мобильного интернета с точки зрения транспортной сети и вариант решения

3G, Wi-Max, LTE, Wi-Max2 — ведётся настоящая война за скорость. Скорость в радиоинтерфейсе. Это хорошо, но напоминает Шфарцнегера с ногами Волочковой, поскольку за радиоинтерфейсом мы упираемся в транспортную сеть. Давайте попробуем найти смысл в этом всём.

Прошлое



Исторически у операторов большой тройки транспортная сеть строилась на основе SDH с последней милей в виде PDH. Пока скорости были небольшие и голоса передавалось больше чем данных, то вполне хватало 1 постоянно выделенного канала E1 на станцию. При внедрении 3G многое поменялось: изменилась система коммутации, радиоподсистемы, но транспортная сеть не изменилась. Сети 3G заточены всё-таки для передачи данных, соответственно трафик от базовых станций (БС) носит спонтанный характер. Основным же недостатком «традиционных» транспортных сетей является невозможность перераспределять полосу между различными БС. Таким образом, для адекватной работы 3G требуется большее количество потоков с меньшей эффективностью.

Настоящее



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

  1. На загруженных направлениям применяется оборудование оптимизации трафика (например, Celtro). Данное решение имеет место быть, т.к. позволяет в условиях ограниченной пропускной способности перераспределять трафик между различными БС. Однако в действительности построить подобную сеть без традиционной тяжело, да и стоимость оборудования довольно высока.
  2. Ethernet поверх SDH. Решение довольно спорное, хотя позволяет обеспечить динамику в распределении. Основной недостаток — большое количество заголовков (SDH, Ethernet, IP, ATM) и как следствие, уменьшение реальной пропускной способности.

В итоге для потребителей это вылилось в невозможность в большинстве случаев получать даже четверть от заявленной скорости 3G.

Будущее


330 Мб/с — скорость несертифицированного Wi-Max2. Чтобы её получить, необходимо подать на БС не меньше 330Мб/с. Это более чем 2 STM. От 10 станций (с учетом того, что с ростом частоты увеличиваются затухания и как следствие при заданной мощности диаметр соты уменьшается, при этом с ростом нагрузки диаметр соты также уменьшается, то 10 станций — это совсем небольшой район) при стандартном подходе требуется не менее 24 STM-1. Данную цифру можно закрыть двумя STM-16, при этом занимая в 2 раза больше волокон, либо одним STM-64. Первый вариант дешевле, но требует развитой волоконной сети. Скорости в бэкбоне трудно представить…

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

Из имеющихся на данный момент технологий задачу распределения нагрузки между станциями может решить ATM и Ethernet. Но, поскольку ATM является компромиссом между данными и голосом, а «новые» сети предназначены больше для передачи данных, то данная технология бесперспективна. Таким образом, остается старый добрый Ethernet с L3 IP. При том, что имеет ужасное отношение заголовка к нагрузке при передачи голоса, стоит вспомнить о превышении объема данных (для которых MTU 1500) над голосовой составляющей (оптимально MTU около 40-60). Стоит упомянуть об опорной сети, точнее о нагрузке на ней. Поскольку объем передаваемых данных огромен, оптимальным решением было бы передача данных по опорной сети через MPLS, поскольку в таком случае возможно уменьшить нагрузку на роутеры и при этом уменьшить время задержки.

Заключение



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

P.S. При положительном обсуждении данная статья будет передана руководству отдельно взятого оператора с целью изменить существующую ситуацию в отдельно взятом городе.