• Подписки в ABBYY Cloud OCR SDK: «заткнитесь и возьмите мои деньги!»

      Хорошая новость™: теперь в ABBYY Cloud OCR SDK помимо разовой покупки страниц можно оформить подписку через PayPal. Мы долго планировали эту разработку, довольно долго она была в состоянии беты для ограниченного круга пользователей. Сейчас подписки доступны всем, а этот пост – о разных технических и социальных моментах этой эпичной разработки.

      Начать нужно с ответа на вопрос «зачем». Ответ на него: подписки удобны и понятны многим пользователям. Хотя покупать пакеты страниц тоже удобно и несложно, пользователю нужно следить за остатком страниц приложения и докупать страницы. Сервис умеет отправлять предупреждение о скором исчерпании остатка страниц, но пользователь может его пропустить. Если пользователь забудет докупить страницы – его приложение может в самый неподходящий момент доизрасходовать остаток страниц и перестать работать.

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

      Мы старались сделать логику подписок как можно более понятной и одновременно удобной для пользователей.
      Читать дальше →
    • Оптимизация сравнения this с нулевым указателем в gcc 6.1



        Хорошие новостиTM ждут пользователей gcc при переходе на версию 6.1 Код такого вида (взят отсюда):

        class CWindow {
            HWND handle;
        public:
            HWND GetSafeHandle() const
            {
                 return this == 0 ? 0 : handle;
            }
        };

        «сломается» — при вызове метода через нулевой указатель на объект теперь может происходить разыменование нулевого указателя, потому что компилятор теперь может просто взять и удалить проверку. Код, конечно, с самого начала сломан, а gcc 6.1 его только немного доломает.
        Читать дальше →
      • Исправлена серьезная ошибка в официальной документации по настройке SSL в web-ролях Microsoft Azure


          Хорошие новостиTM: есть небольшое, но важное развитие сюжета из этого поста, где много букв и долгая история, которая могла отвлечь часть целевой аудитории от необходимости проверить и исправить настройки. После вливания освежающих пул-запросов была обновлена официальная документация, показывающая, как правильно настраивать SSL в веб-ролях Microsoft Azure — один и два. Исправлена серьезная ошибка в примерах настроек.

          Если вы разрабатываете или сопровождаете облачный сервис с веб-ролью, самое время проверить, что настройки SSL указаны правильно и вас не настигнет в самый неподходящий момент волна недовольства пользователей, у которых КРАЙНЕ НЕОЖИДАННО без ясных причин перестало устанавливаться защищенное соединение с вашим сервисом.
          Читать дальше →
        • Как не самое удачное поведение по умолчанию может годами маскировать неправильную работу

            МНОГО ДЕТАЛЕЙОчень удобно, когда благодаря правильно выбранным умолчаниям все работает само и «из коробки» и не нужно ничего настраивать. Эта история о том, что выбранные умолчания должны быть работоспособными всегда, в противном случае есть риск непредвиденного отказа после многих лет беспроблемной работы.

            Мы столкнулись с недокументированным поведением Windows Server в web-ролях Microsoft Azure, которое долгие годы маскировало неправильную настройку нашего сервиса Cloud OCR SDK, пока в один не самый прекрасный момент не привело к серьезным проблемам у отдельных пользователей.
            Читать дальше →
          • Как непродуманные предупреждения компиляторов помогают портить совершенно правильный код

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

              На практике далеко не всегда предупреждения компилятора одинаково полезны. Зачастую они не помогают разработчикам, а мешают им и могут провоцировать на исправление совершенно правильного кода, т.е. на нарушение правила «работает — не трогай».
              Читать дальше →
            • Дорабатываем открытый код — развиваем и показываем всем свои навыки разработки ПО

                Многие начинающие разработчики сталкиваются с необходимостью показать существующий опыт разработки ПО. Даже если вакансия называется «программист без опыта работы», то и без Капитана ясно, что предпочтение будет отдано претенденту, показавшему более-менее внятный код, более-менее подтверждающий наличие полезных в работе навыков.

                Что же делать? Показать решение типового задания с ранних курсов или дипломный проект? Возможно, этого мало? Может быть, написать какую-нибудь впечатляющую программу и заодно получить опыт разработки? Например… калькулятор или компилятор или что там обычно пишут для получения и показа опыта? А если не хватит сил закончить?

                На эти вопросы и сомнения есть один почти универсальный ответ — доработка проектов с открытым кодом. Вы получаете возможность решать реальные проблемы самых разных уровней сложности, результат не только будет работать у сотен-тысяч-миллионов людей во всем мире, но его еще и можно будет показать. Эту возможность иногда упоминают, но обычно на ней не останавливаются. В этот раз — остановимся на ней.
                Читать дальше →
              • Новое предупреждение о неверном вычислении размера массива в gcc 5.1

                  Хорошие новости для пользователей gcc — при использовании gcc 5.1 и выше им будет проще быстро находить вот такую распространенную ошибку вычисления размера массива, объявленного как параметр функции:

                  void something( char arr[100] )
                  {
                      // this loop is broken
                      for( size_t index = 0; index < sizeof(arr)/sizeof(arr[0]); index++ ) {
                         //WHATEVER
                     }
                  }

                  Хотя параметр и объявлен как массив известного размера, с точки зрения компиляторов C и C++ это указатель типа char*, поэтому sizeof(arr) даст то же значение, что и sizeof(char*) – скорее всего, 4 или 8. Цикл, скорее всего, будет работать не так, как ожидалось.
                  Другой вариант:
                  void something( char encryptionKey[9000] )
                  {
                     // WHATEVER, PROFIT
                  
                    // this call is broken
                    SecureZeroMemory( encryptionKey, sizeof(encryptionKey)); // erase the key
                  }

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

                  Чтобы найти такой код было проще, в gcc 5.1 и новее на такой код выдается предупреждение и оно включено по умолчанию.
                  Читать дальше →
                • Городские легенды о медленных вызовах виртуальных функций

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

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

                    В тексте выше ключевое слово «если». Что, если компилятор знает, какую функцию на самом деле надо вызывать?
                    Читать дальше →
                  • Новые оптимизации с использованием неопределенного поведения в gcc 4.9.0

                      Отличные новости ждут пользователей gcc при переходе на версию 4.9.0 – новые оптимизации с использованием неопределенного поведения могут «сломать» (на самом деле — доломать) существующий код, который, например, сравнивает с нулем указатели, ранее переданные в memmove() и ряд других функций стандартной библиотеки.

                      Например, утверждается, что в таком коде:
                      int wtf( int* to, int* from, size_t count ) {
                          memmove( to, from, count );
                          if( from != 0 )
                              return *from;
                          return 0;
                      }
                      

                      новый gcc может удалить сравнение указателя с нулем и в результате вызов wtf( 0, 0, 0 ) будет приводить к разыменованию нулевого указателя (и аварийному завершению программы).
                      Читать дальше →
                    • Ключевое слово volatile и атаки по времени

                        Такие часы плохо подходят для атаки по времениВ библиотеке OpenSSL есть довольно любопытная функция с многообещающим именем CRYPTO_memcmp(). Комментарии к ней объясняют, что обычная memcmp() обладает фатальным недостатком – время ее работы зависит не только от размера сравниваемых блоков, но и от их содержимого, а это может помочь атакующему осуществить так называемую атаку по времени.

                        Аналогичные функции есть в ряде других проектов — поиск по запросу constant time memcmp дает несколько тысяч результатов.

                        Не будем подвергать сомнению необходимость использования функции CRYPTO_memcmp(), а вместо этого рассмотрим, решает ли она поставленную ей задачу.
                        Читать дальше →
                      • Итак, вы пытаетесь оценить надежность своего облачного сервиса

                          SLA (Service Level Agreement) – часто встречающаяся у поставщиков сервиса форма гарантии надежности сервиса. Обычно SLA предлагается в виде оферты – и либо вы довольны и пользуетесь сервисом, либо ищете другой сервис. Типичная формулировка – «industry leading 99,95% monthly uptime SLA», который вроде бы должен устроить большинство пользователей.

                          Обычно потенциальный пользователь, прочитав про «99,95% monthly uptime SLA», бывает очень даже доволен – гарантия отсутствия простоев в течение более чем 21 минуты в месяц длиной 30 дней звучит довольно многообещающе.

                          Все относительно просто, пока вы только потребляете услугу облачного сервиса для собственных нужд. Посмотрели на 99,95%, подумали о не более чем 21 минуте в месяц – впечатлились и довольны. Что если вы сами создаете сервис на основе другого сервиса и решаете, какой SLA вы могли бы предложить?
                          Читать дальше →
                        • Вы все еще кипятите и сравниваете this с нулем?

                            Давным-давно в далекой-далекой галактике широко использовалась библиотека MFC, в которой у ряда классов были методы, сравнивающие this с нулем. Примерно так:

                            class CWindow {
                                HWND handle;
                                HWND GetSafeHandle() const
                                {
                                     return this == 0 ? 0 : handle;
                                }
                            };
                            

                            «Это же не имеет смысла» – возразит читатель. Еще как «имеет»: этот код «позволяет» вызывать метод GetSafeHandle() через нулевой указатель CWindow*. Такой прием время от времени используется в разных проектах. Рассмотрим, почему на самом деле это плохая идея.
                            Читать дальше →
                          • Компилируем код из кода для воспроизведения гонки двух процессов

                              Класс CSharpCodeProvider позволяет программе на C# компилировать код на C#. Обычный вопрос – «зачем». Обычные ответы:
                              1. исполнение кода, данного пользователями, как на ideone.com,
                              2. «ну мало ли зачем» и
                              3. «а это уже отдельный вопрос»

                              Сегодня мы используем этот класс для удобного воспроизведения гонки двух процессов.
                              Читать дальше →
                            • Облачные сервисы Windows Azure и убийственная звездочка

                                Одной из удобных плюшек облачных сервисов Windows Azure (PaaS, так называемые web и worker роли) является отсутствие необходимости устанавливать, настраивать и поддерживать операционную систему. Вместо этого разработчик может сосредоточиться на разработке начинки сервиса, которую затем в виде специального пакета он публикует в облако, после чего инфраструктура Windows Azure разворачивает его на виртуальных машинах с уже установленной, настроенной и оптимально пропатченной операционной системой, которую затем при необходимости сама же может обновить.

                                За все приходится платить. Если что-то звучит слишком хорошо, это неспроста. По умолчанию инфраструктура Windows Azure может в произвольный момент обновить операционную систему и далеко не факт, что после обновления ваш сервис сможет продолжить работу.

                                Рассмотрим подробно, как это происходит.
                                Читать дальше →
                                • +14
                                • 7,2k
                                • 5
                              • Облака, ответственность и неожиданные ситуации с SSL-сертификатами

                                  При обсуждении облачных платформ вполне естественно возникает вопрос о надежности платформы и об ответственности провайдера за ее неполадки. При этом ожидания пользователей самые высокие – все должно идеально работать 25 часов в сутки, 9 дней в неделю и все дни в году. В реальном мире возникают всевозможные проблемы – то при отключении внешнего электроснабжения не отработает переход на резервное, то на дне емкости с дизтопливом окажется конденсат (вода), то 29 февраля «через год» вычислят увеличением года на единицу.

                                  Не последнее место в списке проблем занимают сертификаты для SSL. Например, совершенно неожиданно может истечь срок действия сертификата какого-нибудь облачного сервиса.

                                  Кто виноват, и что делать?
                                  Читать дальше →
                                • Однажды вы читали о ключевом слове volatile…

                                  • Tutorial
                                  В C и C++ есть ключевое слово volatile, которое указывает компилятору, что значение в соответствующей области памяти может быть изменено в произвольный момент и потому нельзя оптимизировать доступ к этой области. Обычно описание ключевого слова сразу приводит пример с данными, которые могут быть в любой момент изменены из другой нити, аппаратным обеспечением или операционной системой. Прочитав описание примера, большинство читателей глубоко зевает, решает, что в этой жизни им такое не понадобится, и переходит к следующему разделу.

                                  Сегодня рассмотрим менее экзотический сценарий использования ключевого слова volatile.

                                  Читать дальше →
                                • Облака и эластичность

                                    Sooo elastic
                                    Планируя разработку облачных сервисов, многие разработчики задаются вопросом – что нового им предстоит и чем облачный сервис отличается от «обычного».

                                    Довольно часто при описании облаков и облачных решений говорят об эластичности. Amazon даже назвала свое облако Elastic Compute Cloud (EC2). Помимо того, что «эластичность» – используемое в маркетинге облаков красивое слово, у него есть и вполне определенный смысл. Речь о возможности арендовать вычислительные ресурсы с оплатой по фактическому использованию, начиная и прекращая аренду в произвольный момент.

                                    Это очень удобно для сервисов с непостоянной нагрузкой – при изменении нагрузки они могут масштабироваться, увеличивая или уменьшая число узлов, обеспечивая пользователям приемлемое время обработки запросов, а владельцам – снижение затрат.

                                    Так в теории. На практике перейти от красивого слова к делу не всегда просто.

                                    Читать дальше →
                                  • Итак, вы решили запретить копирование объектов класса в C++

                                      SHALL NOT DANCE THEREДовольно часто можно встретить код на C++, в котором у одного или нескольких классов конструктор копирования и оператор присваивания объявлены private и написан комментарий вида «копирование запрещено».

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

                                      Рассмотрим возможные проблемы.
                                      Читать дальше →
                                    • Облако — что это и зачем?

                                        Недавно мы запустили сервис ABBYY Cloud OCR SDK, работающий на облаке Windows Azure и попутно набрали 100500 опыта. Например, узнали, что многие используют слово «облако» и слышали, что «облака – это модно», но очень немногие понимают, что такое облако и главное – зачем делать сервис именно в облаке. Слово «облако» повсеместно используется и, похоже, начало обрастать городскими легендами.

                                        Посмотрите, например, вот это видео:



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

                                        Рассмотрим подробно, что такое публичное облако, зачем может иметь смысл использовать его для работы ПО и правда ли, что «скоро все будет в облаках».

                                        Читать дальше →
                                      • Итак, вы хотите заглушить это предупреждение в Visual C++…

                                          FAILОбычная ситуация: вы написали кусок безупречно правильного кода, но Visual C++ выдает на нем предупреждение. Часто можно немного переписать код, чтобы предупреждение ушло, но не всегда, и тогда выход один – глушить выдачу этого предупреждения.

                                          Рассмотрим, какие возможности для этого есть в Visual C++ и какие ошибки допускают при их использовании.

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