...

суббота, 3 января 2015 г.

Интересное по хабу .Net за 2014 год. Часть 1


сегодня в 15:05


Мы с вами люди рабочие и зачастую не замечаем ничего что происходит за пределами нашей работы. Так и я, работая изо дня в день, знаю только про свой SpecFlow и смежные вопросы. Но ничего – по сторонам. Этим постом я хочу восполнить пробелы новостей в области .Net

Новости хаба .Net на Хабре занимают 33 страницы или 328 постов. Что говорит о том что новости появляются почти каждый день =) Посмотрим на самое интересное из них (на мой скромный взгляд). Ну и загляните под кат: до ката, конечно же, не все.


Доступен новый JIT: теперь с поддержкой SIMD

Microsoft раскрыла исходный код компилятора С#

Consulo: ~1000 коммитов, или как прошла осень

Под капотом у Stopwatch

Как тестировать код финализатора (c#). Послесловие: тест все-таки упал

Получение указателя на объект .Net

Детали реализации стека — часть первая

Детали реализации стека — часть вторая

Fody и его плагины

Парсинг почтовых адресов из строки на C#

iOS vs WPF — сложное против мелкомягкого

Улучшаем производительность: boxing в .NET, которого можно избежать

Проект dot42 переходит на новый формат (C# 2 Java)

Введение в XWT

Анонсирован Xamarin 3

String.Intern делает строки ещё интереснее

Окно сообщения об ошибке для WinForms и WPF приложений

Бот для DirectX-аркады. Часть №1: устанавливаем контакт

Бот для аркады. Часть №2: подключаем OpenCV

Некоторые тонкости GetHashCode

Котфускация исполняемого .net кода

Улучшаем производительность: полезные советы и приёмы в .NET

SynchronizationContext — когда MSDN подводит

Улучшаем LINQ для работы с IReadOnly-коллекциями

Эти занимательные региональные настройки

Пишем под ТСД. Подключение сканера штрихкода, как компонент формы


Также, поскольку за данные посты уже не проголосовать, призываю голосовать в карму авторам, если посты вам понравились =)






2046


45





Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Эволюция Zeus. Part III

Предыдущая часть здесь.

image



Крестовый поход




В конце марта 2012 Microsoft провела комплекс мероприятий под кодовым названием Operation b71, направленных на вывод из строя некоторых элементов инфраструктуры Zeus, а также SpyEye и Ice IX (проект, базирующийся на исходниках Zeus). В результате была прекращена работа командных серверов на двух хостингах: в городах Скрэнтон (Пенсильвания) и Ломбард (Иллинойс). Также из управляющей структуры ботнетов были изъяты два IP-адреса и около 800 доменов.

Эта операция подверглась резкой критике со стороны комьюнити специалистов в сфере безопасности IT. В частности, специалисты компании Fox-IT отметили, что Microsoft в своих отчетных документах не только раскрыла информацию о подозреваемых, включая авторов и индивидуальных пользователей, но и совершенно не связанных с ними лиц. При этом все эти данные были достоянием IT security сообщества и не подлежали разглашению в связи с проведением оперативно-розыскных мероприятий. Кроме того, некоторые доменные имена принадлежали легальным, но взломанным ресурсам. Помимо всего прочего, было установлено, что, несмотря на заявление Microsoft, что для изъятых доменных имен просто происходил разрыв соединения, это было не так и процесс синкхолинга шел полным ходом, то есть в ходе него не только сохранялись IP адреса пострадавших, но также записывались HTTP запросы со всеми заголовками, которые, фактически, могли включать различную конфиденциальную информацию, в том числе имена пользователей, адреса электронной почты, пароли и т.д.


К тому же данная операция почти никак не отразилась на ботсети Zeus Gamover. Вот так и работает Microsoft, много пиара плюс подстава своих коллег по цеху ради минуты славы. В материалах фигурируют Slavik и Gribodemon, к личностям которых мы еще вернемся.


Тем не менее, раскручивая цепочку связей киберпреступников, специалисты также взяли под прицел троян Citadel и его разработчика AquaBox. Тот, явно заметив пристальное внимание к своей персоне, в конце 2012 года лег на дно и прекратил открытую продажу своего продукта.


Решающий удар по инфраструктуре Citadel был нанесен в мае-июне 2013 в ходе мероприятия Operation b54, проводимого совместно специалистами Microsoft и ФБР. Суть операции заключалась в том, чтобы изъять 4000 доменных имен, которые использовались Citadel. По факту было изъято 1462 доменных имен, для них было сделано перенаправление на сервера Microsoft для синкхола. По оценкам специалистов всего трояном Citadel были заражены порядка 5 млн компьютеров, преимущественно в США, Европе, Гонконге, Сингапуре, Индии и Австралии.


Но и тут Microsoft не могла не налажать. Как выяснилось, порядка 1000 доменных имен принадлежали другим security компаниям и использовались именно для наблюдения. На это обстоятельство обратил внимание владелец трекера abuse.ch Роман Хюсси, у которого одномоментно пропало порядка 300 доменных имен, используемых для синкхола.


Конечная цель перехвата управления — рассылка специально сформированных в Microsoft конфигурационных файлов для Citadel, в которых снималась блокировка сайтов антивирусных компаний. Эта фишка, перенаправление для сайтов из black list, была отличительной для Citadel, она появилась в версии 1.3.5.1 Rain Edition, в оригинальном Zeus ее не было. И тут возникает естественный вопрос этического характера, а какие еще команды могла потенциально отдать Microsoft через «свой» конфиг? А вообще странно, что разработчики Citadel не внедрили механизм цифровой подписи конфигурационного файла.


Между тем, разработчики Citadel продолжали закрытые продажи. В июне 2013 специалисты Trend Micro обнаружили версию Citadel 3.1.0.0, которая имела функцию распространения через USB устройства. А в июле в прессе появились сообщения, что банковские системы Японии атакованы как раз при помощи такой версии. Было выявлено 9 командных серверов, к которым шли обращения с около 20 тысяч уникальных IP адресов, при этом 96% инфицированных систем находились в Японии.


Шумиха и неразбериха




Пока безопасники боролись с многочисленными вариациями Zeus версии 2 (небольшое отступление — информация о x64 версии Zeus 2 c C&C в сети TOR от декабря 2013 года здесь), на андеграундной сцене появился KINS — Kasper Internet Non Security. По информации компании Fox-IT, приватная версия KINS, почти полностью основанная на исходных кодах Zeus, с декабря 2011 года использовалась для атак банковских систем Германии и Нидерландов. А дальше начинается некоторая путаница. Дело в том, что пристальное внимание к KINS было обращено много позднее, в 2013 году.

Как тут уже упоминалось, в 2012-2013 прошла волна операций против банковских троянов. Кроме Operation b71 и Operation b54, в 2012 году были произведены массовые аресты членов кибергруппировок, использовавших Carberp, которые закончились арестом разработчиков Carberp на Украине в марте 2013 года. Так, или иначе, андеграунд с 2012 года стал остро нуждаться в очередном инструменте с соответствующей поддержкой для банковских грабежей.


Судя по всему, название KINS впоследствии стали использовать в качестве своеобразной торговой марки, то есть в 2013 выпустили относительно новый продукт, который безопасники начали называть по старому — KINS. Однако правильнее эту версию все-таки называть PowerZeus или ZeusVM.


Отличительные особенности этой версии:



  • использование VMProtect для затруднения своего анализа (отсюда ZeusVM);

  • детект выполнения своего кода в среде виртуальных машин и песочниц;

  • использование SSL для связи с командным центром;

  • удаление своего ключа автозапуска при старте и восстановление перед перезагрузкой.




Кроме того, заметно, что базой для дроппера послужил PowerLoader 2 (отсюда PowerZeus). Фактически в нем используется исходный код грабберов Zeus и SpyEye в виде dll в качестве модулей. Французский исследователь Xylitol провел свое исследование KINS на основе исходных кодов, и пришел к выводу, что KINS = Zeus 2.0.8.9 + Power Loader 2.0 + SpyEye Plugins. Интересно, что в ходе своего исследования Xylitol вышел на разработчика KINS, его Jabber он получил из взломанной тестовой админки KINS. С разработчиком состоялся довольно-таки интересный диалог.

В ходе диалога выяснилось, что его наняли для разработки KINS, но потом «что-то пошло не так». Все его наработки были украдены в ходе взлома, и тот исходный код KINS, который слили в сеть, является очень сырой альфой конечного продукта. Так или иначе, разработка и закрытая продажа KINS ведется, а KINS и ZeusVM стали форками, разрабатываемыми разными командами.


ZeusVM, в частности, использовался в ходе атак Польских систем ДБО летом 2013 года. Отличительной особенностью атаки было то, что конфиг с веб-инжектами не подгружался из Интернета (хотя ссылка на URL конфига была), а целиком содержался внутри одной из секций PE файла.


В ходе разработки ZeusVM дополнительно были реализованы такие фишки, как использование стеганографии (ноябрь 2013), когда конфиг после обработки xor, rc4 и base64, внедрялся в изображение формата jpg, а так же изменение механизма установки хуков (май 2014), позаимствованное из Carberp. Последнее изменение многие поспешили проанонсировать, как очередной супер крутой гибрид Zeus и Carberp под названием Zberp, однако реально это очередная пугалка.


Текущее положение дел показывает, что, в большинстве своем, киберпреступники перешли с использования Citadel на ZeusVM.


Конец игры?




Как видно, несколько форков Zeus развиваются параллельно несколькими командами злоумышленников. Вернемся снова к «основной» ветке Zeus под названием GameOver (он же Murofet). Всего можно выделить три его версии:


  • версия 1, распространялась с сентября 2011, впервые реализована P2P функциональность, в качестве резервного канала используется DGA;

  • версия 2, обнаружена в феврале 2012, в этой версии были усовершенствованы как алгоритм DGA, так и механизм P2P;

  • версия 3, начала распространяться в июле 2014 года, отличительной особенностью ее является использование алгоритма Fast Flux для работы с командным сервером, при этом функциональность P2P была полностью удалена.




Версия 3 появилась после очередной операции с названием «Tovar», проведенной с апреля по июнь 2014 года совместными усилиями ФБР, Европола и ряда компаний, работающих в сфере информационной безопасности, таких как CrowdStrike, Dell SecureWorks, Symantec, Trend Micro и McAfee. В ходе расследования было установлено, что управление Zeus GameOver осуществлялось с помощью более чем десяти серверов, которые размещались на абузоустойчивой площадке одного из хостинг-провайдеров Одессы. Таким образом, главный управляющий центр был обезврежен.

В результате раскрытия хакерской группировки Zeus GameOver был назван один из предполагаемых организаторов — 30-летний житель России Евгений Богачёв, он объявлен ФБР в розыск. Ему предъявлены заочные обвинения на основании перехваченных переговоров в одном из чатов. В них Богачёв, пишущий под никами Lucky12345 и Slavik, признаётся собеседнику, что является создателем трояна Zeus.


Кстати, в 2013 году власти США заявили об аресте гражданина России Александра Панина, который был задержан 28 июня сотрудниками Интерпола и экстрадирован из Доминиканской Республики в США. 28 января 2014 года на суде в Атланте Панин признал, что он являлся одним из разработчиков SpyEye и его псевдоним — Gribodemon. Как знать, не через Панина ли правоохранительные органы вышли на Богачева?


По информации Интерпола, более 1 млн. компьютеров по всему миру были инфицированы Zeus GameOver, совокупный финансовый ущерб от кражи из систем ДБО оценивается в 75 миллионов евро. Кроме того, посредством Zeus GameOver на 234 тысячи компьютеров было установлено вредоносное ПО CryptoLocker, при помощи которого был собран «выкуп» в размере 27 миллионов долларов США. Для распространения Zeus GameOver использовались мощности ботнета Cutwail и загрузчик PonyLoader.


В августе 2013 года эксперты Dell SecureWorks Counter Threat Unit обнаружили, что в дополнение к PonyLoader для распространения Zeus GameOver киберпреступники используют новый загрузчик Upatre. Его файл имеет небольшой размер и является предельно простым. Upatre использует SSL-соединение для загрузки и запуска необходимого вредоносного файла, URL которого жестко задан внутри кода загрузчика. Также, как и Pony Loader, Upatre распространялся посредством спам-ботнета Cutwail в виде аттача, представляющего собой архив zip.


С конца января схема была несколько усовершенствована, исполняемый файл Zeus GameOver подвергался сжатию, шифровался операцией xor с использованием 32 разрядного ключа, а полученному файлу присваивалось расширение .enc. При расшифровке обновленная версия Upatre обращает этот процесс и получает исходный исполняемый файл.


С февраля 2014 года Zeus GameOver обзавелся руткитом Necurs для сокрытия своего присутствия. Дроппер содержал x86 и x64 версии драйвера режима ядра. Для поднятия привилегий, если нет прав администратора, необходимых для установки драйвера, используется эксплоит CVE-2010-4398. Драйвер x64 подписан, но поскольку сертификат не входит в перечень доверенных, для обхода PathGuard вызывается штатная утилита bcdedit.exe для установки опции загрузки TESTSIGNING.


Так или иначе, после операции «Tovar» Zeus GameOver никуда не исчез. Очередная его версия, без P2P, Necurs и с поддержкой Fast Flux продолжает распространяться киберпреступниками.


Новый виток спирали




В декабре 2014 года сотрудники Лаборатории Касперского сообщили об обнаружении новой версии Zeus, получившей название Chthonic. Эта версия представляет собой своеобразный гибрид загрузчика Andromeda и ZeusVM. Chthonic имеет модульную структуру, на сегодняшний день обнаружены следующие модули:

  • main — основной модуль (версия 4.6.15.0 — v4.7.0.0);

  • info — сбор информации о системе;

  • pony — модуль для кражи сохраненных паролей;

  • klog — кейлоггер;

  • http — модуль вебинжектов и formgrabber;

  • vnc — удаленный доступ;

  • socks — прокси;

  • cam_recorder — запись видео с вебкамеры.




По номеру версии видно, что эволюция Zeus идет полным ходом. Тем более, что летом 2014 на черном рынке появились новые игроки в сфере банковских троянов — Pandemiya и Kronos (небольшой технический анализ здесь), не использующие исходных кодов Zeus и Carberp.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


PVS-Studio покопался во внутренностях Linux (3.18.1)

Linux and PVS-Studio

Соавтор: Святослав Размыслов SvyatoslavMC.

В рекламных целях мы решили попробовать проверить ядро Linux с помощью нашего статического анализатора кода. Эта задача интересна своей сложностью. Исходные коды Linux чем только не проверялись и проверяются. Поэтому найти хоть что-то новое, весьма сложная задача. Но если получится, то это будет хорошая рекламная заметка о возможностях анализатора PVS-Studio.



Что мы проверяли




Ядро Linux было взято с сайта The Linux Kernel Archives. Проверялась Latest Stable Kernel 3.18.1.

К тому моменту, как я пишу эту статью, уже появилось ядро 3.19-rc1. К сожалению, проверка проекта и написание статьи занимают немало времени. Поэтому будем довольствоваться проверкой не самой последней версии.


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



  1. Мы регулярно проверяем большое количество проектов. Помимо бесплатной проверки проектов, у нас много других задач. И поэтому нет никакой возможности начинать всё сначала, только потому, что появилась новая версия. Так мы можем никогда ничего не опубликовать :).

  2. 99% найденных ошибок осталось на своём месте. Так что эту статью смело можно использовать чтобы немного улучшить код ядра Linux.

  3. Цель статьи — реклама PVS-Studio. Если мы можем найти ошибки в проекте версии X, то мы сможем найти что-то и в версии Y. Наши проверки достаточно поверхностны (мы не знакомы с проектом) и их целью является написание вот таких статей. Настоящую пользу проекту приносит приобретение лицензии на PVS-Studio и его регулярное использование.




Как мы проверяли




Для проверки ядра использовался статический анализатор кода PVS-Studio версии 5.21.

Для проверки Linux Kernel был использован дистрибутив Ubuntu-14.04, для которого имелось много подробных инструкций по конфигурированию и сборке ядра. Анализатор проверяет препроцессированные файлы, которые лучше получать для успешно компилируемых файлов, поэтому сборка проекта один из самых важных этапов проверки.


Далее была написана небольшая утилита на C++, которая для каждого запущенного процесса компилятора сохраняла командную строку, текущую директорию и переменные окружения. Читателям, знакомым с продуктами PVS-Studio, должна сразу вспомниться утилита PVS-Studio Standalone, которая позволяет проверить любой проект под Windows. Там для обращения к процессам используется WinAPI, поэтому для Linux данный механизм мониторинга был переписан, остальной же код, связанный с запуском препроцессирования и проверки, был полностью перенесён, и проверка ядра Linux стала лишь вопросом времени.


В начале о безопасности




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

Можно по-разному воспринимать те сообщения, которые выдаёт PVS-Studio. Например, с одной стороны это опечатка, а с другой может быть уязвимостью. Всё зависит от точки зрения.


Хочу предложить рассмотреть несколько предупреждений, которые PVS-Studio выдал при анализе Linux. Я не говорю, что анализатор нашёл уязвимость в Linux. Но рассматриваемые предупреждения вполне могли бы это сделать.


Опасное использование функции memcmp()



static unsigned char eprom_try_esi(
struct atm_dev *dev, unsigned short cmd,
int offset, int swap)
{
unsigned char buf[ZEPROM_SIZE];
struct zatm_dev *zatm_dev;
int i;

zatm_dev = ZATM_DEV(dev);
for (i = 0; i < ZEPROM_SIZE; i += 2) {
eprom_set(zatm_dev,ZEPROM_CS,cmd); /* select EPROM */
eprom_put_bits(zatm_dev,ZEPROM_CMD_READ,ZEPROM_CMD_LEN,cmd);
eprom_put_bits(zatm_dev,i >> 1,ZEPROM_ADDR_LEN,cmd);
eprom_get_byte(zatm_dev,buf+i+swap,cmd);
eprom_get_byte(zatm_dev,buf+i+1-swap,cmd);
eprom_set(zatm_dev,0,cmd); /* deselect EPROM */
}
memcpy(dev->esi,buf+offset,ESI_LEN);
return memcmp(dev->esi,"\0\0\0\0\0",ESI_LEN);
}




Предупреждение PVS-Studio: V642 Saving the 'memcmp' function result inside the 'unsigned char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. zatm.c 1168

Обратите внимание на оператор 'return' в самом конце тела функции.


Функция 'memcmp' возвращает следующие значения типа 'int':



  • < 0 — buf1 less than buf2;

  • 0 — buf1 identical to buf2;

  • > 0 — buf1 greater than buf2;




Обратите внимание:

  • "> 0", означает любые числа, а вовсе не 1;

  • "< 0", это не обязательно -1.


Возвращаемыми значениями могут быть: -100, 2, 3, 100, 256, 1024, 5555 и так далее. Это значит, что этот результат нельзя преобразовывать в тип 'unsigned char' (это тип, который возвращает функция).

В результате неявного приведения типа могут быть отброшены значащие биты, что приведет к нарушению логики выполнения программы.


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


Ну и что? Подумаешь, неправильно будет проверено что-то, связанное с EPROM. Ошибка, конечно, но при чём тут уязвимость?


А то, что диагностика V642 может выявить и уязвимость! Не верите? Пожалуйста, вот идентичный код из MySQL/MariaDB.



typedef char my_bool;
...
my_bool check(...) {
return memcmp(...);
}




Не PVS-Studio нашёл эту ошибку. Но мог бы.

Эта ошибка послужила причиной серьезной уязвимости в MySQL/MariaDB до версий 5.1.61, 5.2.11, 5.3.5, 5.5.22. Суть в том, что при подключении пользователя MySQL /MariaDB вычисляется токен (SHA от пароля и хэша), который сравнивается с ожидаемым значением функцией 'memcmp'. На некоторых платформах возвращаемое значение может выпадать из диапазона [-128..127]. В итоге, в 1 случае из 256 процедура сравнения хэша с ожидаемым значением всегда возвращает значение 'true', независимо от хэша. В результате, простая команда на bash даёт злоумышленнику рутовый доступ к уязвимому серверу MySQL, даже если он не знает пароль. Причиной этому стал код в файле 'sql/password.c', показанный выше. Более подробное описание этой проблемы можно прочитать здесь: Security vulnerability in MySQL/MariaDB.


Вернёмся теперь к Linux. Вот ещё один опасный фрагмент кода:



void sci_controller_power_control_queue_insert(....)
{
....
for (i = 0; i < SCI_MAX_PHYS; i++) {
u8 other;
current_phy = &ihost->phys[i];

other = memcmp(current_phy->frame_rcvd.iaf.sas_addr,
iphy->frame_rcvd.iaf.sas_addr,
sizeof(current_phy->frame_rcvd.iaf.sas_addr));

if (current_phy->sm.current_state_id == SCI_PHY_READY &&
current_phy->protocol == SAS_PROTOCOL_SSP &&
other == 0) {
sci_phy_consume_power_handler(iphy);
break;
}
}
....
}




Предупреждение PVS-Studio: V642 Saving the 'memcmp' function result inside the 'unsigned char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. host.c 1846

Результат работы функции memcmp() помещается в переменную other, имеющую тип unsigned char. Не думаю, что эта какая-то уязвимость, но работа SCSI контроллер в опасности.


Ещё парочку таких мест можно найти здесь:



  • V642 Saving the 'memcmp' function result inside the 'unsigned char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. zatm.c 1168

  • V642 Saving the 'memcmp' function result inside the 'unsigned char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. host.c 1789




Опасное использование функции memset()




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

Рассмотрим пример неправильного кода:



static int crypt_iv_tcw_whitening(....)
{
....
u8 buf[TCW_WHITENING_SIZE];
....
out:
memset(buf, 0, sizeof(buf));
return r;
}




Предупреждение PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'buf' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. dm-crypt.c 708

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


При этом, заметить такую ошибку крайне сложно. Написать юнит-тест сложно. Под отладчиком такая ошибка тоже не будет видна (в Debug-версии будет присутствовать вызов функции memset).


При этом хочу подчеркнуть. Это не «теоретически-возможное поведение компилятора», а очень даже практическое. Компиляторы действительно удаляют вызов функции memset(). Подробнее про это можно прочитать в описании диагностики V597.


PVS-Studio неуместно рекомендует использовать функцию RtlSecureZeroMemory(), так как ориентирован на Windows. В Linux такой функции, конечно, нет. Но здесь главное предупредить, а подобрать нужную функцию уже не сложно.


Следующий аналогичный пример:



static int sha384_ssse3_final(struct shash_desc *desc, u8 *hash)
{
u8 D[SHA512_DIGEST_SIZE];

sha512_ssse3_final(desc, D);

memcpy(hash, D, SHA384_DIGEST_SIZE);
memset(D, 0, SHA512_DIGEST_SIZE);

return 0;
}




Предупреждение PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'D' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. sha512_ssse3_glue.c 222

А ниже пример, где могут быть не обнулены сразу 4 буфера: keydvt_out, keydvt_in, ccm_n, mic. Код взят из файла security.c (строки 525 — 528).



int wusb_dev_4way_handshake(....)
{
....
struct aes_ccm_nonce ccm_n;
u8 mic[8];
struct wusb_keydvt_in keydvt_in;
struct wusb_keydvt_out keydvt_out;
....
error_dev_update_address:
error_wusbhc_set_gtk:
error_wusbhc_set_ptk:
error_hs3:
error_hs2:
error_hs1:
memset(hs, 0, 3*sizeof(hs[0]));
memset(&keydvt_out, 0, sizeof(keydvt_out));
memset(&keydvt_in, 0, sizeof(keydvt_in));
memset(&ccm_n, 0, sizeof(ccm_n));
memset(mic, 0, sizeof(mic));
if (result < 0)
wusb_dev_set_encryption(usb_dev, 0);
error_dev_set_encryption:
kfree(hs);
error_kzalloc:
return result;
....
}




И последний пример, где в памяти остаётся «болтаться» какой-то пароль:

int
E_md4hash(const unsigned char *passwd, unsigned char *p16,
const struct nls_table *codepage)
{
int rc;
int len;
__le16 wpwd[129];

/* Password cannot be longer than 128 characters */
if (passwd) /* Password must be converted to NT unicode */
len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
else {
len = 0;
*wpwd = 0; /* Ensure string is null terminated */
}

rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
memset(wpwd, 0, 129 * sizeof(__le16));

return rc;
}




Предупреждение PVS-Studio: V597 The compiler could delete the 'memset' function call, which is used to flush 'wpwd' buffer. The RtlSecureZeroMemory() function should be used to erase the private data. smbencrypt.c 224

На этом остановлюсь. Ещё 3 неудачных memset() можно найти здесь:



  • sha256_ssse3_glue.c 214

  • dev-sysfs.c 104

  • qp.c 143




Опасные проверки




У анализатора PVS-Studio есть диагностика V595, которая выявляет ситуации, когда указатель в начале разыменовывается, а потом проверяется на равенство NULL. Иногда с этой диагностикой всё просто и понятно. Рассмотрим такой простой случай:

static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n)
{
struct net *net = sock_net(skb->sk);
struct nlattr *tca[TCA_ACT_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
....
}




Предупреждение PVS-Studio: V595 The 'skb' pointer was utilized before it was verified against nullptr. Check lines: 949, 951. act_api.c 949

Здесь всё просто. Если указатель 'skb' будет равен нулю, то быть беде. Указатель разыменовывается в первой строке.


Следует отметить, что анализатор ругается не потому, что увидел разыменование непроверенного указателя. Так было бы слишком много ложных срабатываний. Ведь не всегда аргумент функции может быть равен 0. Возможно, проверка осуществлялась где-то ещё.


Логика работы иная. PVS-Studio считает код опасным, если указатель разыменовывается, а потом ниже проверяется. Если указатель проверяют, то предполагают, что он может быть равен 0. Следовательно это повод выдать предупреждение.


С этим простым примером разобрались. Но нам интересен вовсе не он.


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



static int podhd_try_init(struct usb_interface *interface,
struct usb_line6_podhd *podhd)
{
int err;
struct usb_line6 *line6 = &podhd->line6;

if ((interface == NULL) || (podhd == NULL))
return -ENODEV;
....
}




Предупреждение PVS-Studio: V595 The 'podhd' pointer was utilized before it was verified against nullptr. Check lines: 96, 98. podhd.c 96

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


Пусть указатель podhd равен NULL. Некрасиво выглядит выражение &podhd->line6. Но ошибки нет. Здесь нет доступа к памяти. Просто вычисляется адрес одного из членов класса. Да, значение указателя 'line6' некорректно. Оно указывает «в никуда». Но ведь этот указатель не используется. Вычислили некорректный адрес, ну и что? Ниже в коде расположена проверка и если 'podhd', то функция завершит свою работу. Указатель 'line6' нигде не используется, а значит на практике никакой ошибки не будет.


Господа, вы не правы! Так делать всё равно нельзя. Не ленитесь и исправляйте такой код.


При оптимизации компилятор рассуждает так. Вот здесь указатель разыменовывается: podhd->line6. Ага, программист знает что делает. Значит указатель здесь точно не равен нулю. Отлично, запомним это.


Дальше компилятор встречает проверку:



if ((interface == NULL) || (podhd == NULL))
return -ENODEV;




И оптимизирует её. Он считает, что указатель 'podhd' не равен нулю. Поэтому он сократит проверку до:

if ((interface == NULL))
return -ENODEV;




Как и в случае с memset() дополнительная сложность в том, что мы не увидим отсутствие проверки в Debug() версии. Такую ошибку очень сложно искать.

В результате, если передать в функцию нулевой указатель, то функция не вернёт статус (-ENODEV), а продолжит свою работу. Последствия могут быть непредсказуемы.


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


Ещё один подобный пример:



int wpa_set_keys(struct vnt_private *pDevice, void *ctx,
bool fcpfkernel) __must_hold(&pDevice->lock)
{
....
if (is_broadcast_ether_addr(&param->addr[0]) ||
(param->addr == NULL)) {
....
}




Предупреждение PVS-Studio: V713 The pointer param->addr was utilized in the logical expression before it was verified against nullptr in the same logical expression. wpactl.c 333

Компилятор при оптимизации может сократить проверку до:



if (is_broadcast_ether_addr(&param->addr[0]))



Ядро Linux большое. Так что предупреждений V595 было выдано более 200 штук. К своему стыду, я поленился их просматривать и выбрал только один пример для статьи. Остальные подозрительные места я предлагаю изучить кому-то из разработчиков. Я привожу их списком: Linux-V595.txt.

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


Найденные подозрительные места




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

Некорректные логические условия



void b43legacy_phy_set_antenna_diversity(....)
{
....
if (phy->rev >= 2) {
b43legacy_phy_write(
dev, 0x0461, b43legacy_phy_read(dev, 0x0461) | 0x0010);
....
} else if (phy->rev >= 6)
b43legacy_phy_write(dev, 0x049B, 0x00DC);
....
}




Предупреждение PVS-Studio: V695 Range intersections are possible within conditional expressions. Example: if (A

Второе условие никогда не выполняется. Для наглядности упростим код:



if ( A >= 2)
X();
else if ( A >= 6)
Y();




Как видите, не существует такого значения в переменной 'A', при котором будет вызвана функция Y().

Рассмотрим другие похожие случаи. В пояснении они не нуждаются.



static int __init scsi_debug_init(void)
{
....
if (scsi_debug_dev_size_mb >= 16)
sdebug_heads = 32;
else if (scsi_debug_dev_size_mb >= 256)
sdebug_heads = 64;
....
}




Предупреждение PVS-Studio: V695 Range intersections are possible within conditional expressions. Example: if (A

static ssize_t ad5933_store(....)
{
....
/* 2x, 4x handling, see datasheet */
if (val > 511)
val = (val >> 1) | (1 << 9);
else if (val > 1022)
val = (val >> 2) | (3 << 9);
....
}




Предупреждение PVS-Studio: V695 Range intersections are possible within conditional expressions. Example: if (A

Есть ещё парочка схожих ситуаций, которые не буду приводить, чтобы не делать статью излишне длинной:



  • V695 Range intersections are possible within conditional expressions. Example: if (A < 5) {… } else if (A < 2) {… }. Check lines: 1417, 1422. bnx2i_hwi.c 1422

  • V695 Range intersections are possible within conditional expressions. Example: if (A < 5) {… } else if (A < 2) {… }. Check lines: 4815, 4831. stv090x.c 4831


Теперь рассмотрим другую разновидность подозрительных условий.

static int dgap_parsefile(char **in)
{
....
int module_type = 0;
....
module_type = dgap_gettok(in);
if (module_type == 0 || module_type != PORTS ||
module_type != MODEM) {
pr_err("failed to set a type of module");
return -1;
}
....
}




Предупреждение PVS-Studio: V590 Consider inspecting the 'module_type == 0 || module_type != 68' expression. The expression is excessive or contains a misprint. dgap.c 6733

Я не знаком с кодом и у меня нет идей, как должна выглядеть эта проверка. Поэтому воздержусь от комментариев. Вот ещё одно похожее место:



  • V590 Consider inspecting the 'conc_type == 0 || conc_type != 65' expression. The expression is excessive or contains a misprint. dgap.c 6692




«Вырви глаз»




В ходе изучения сообщений анализатора я встретил функцию name_msi_vectors(). Она хоть и короткая, но читать ее совершенно не хочется. Видимо, именно поэтому она содержит очень подозрительную строчку.

static void name_msi_vectors(struct ipr_ioa_cfg *ioa_cfg)
{
int vec_idx, n = sizeof(ioa_cfg->vectors_info[0].desc) - 1;

for (vec_idx = 0; vec_idx < ioa_cfg->nvectors; vec_idx++) {
snprintf(ioa_cfg->vectors_info[vec_idx].desc, n,
"host%d-%d", ioa_cfg->host->host_no, vec_idx);
ioa_cfg->vectors_info[vec_idx].
desc[strlen(ioa_cfg->vectors_info[vec_idx].desc)] = 0;
}
}




Предупреждение: V692 An inappropriate attempt to append a null character to a string. To determine the length of a string by 'strlen' function correctly, a string ending with a null terminator should be used in the first place. ipr.c 9409

Подозрительной является последняя строка:



ioa_cfg->vectors_info[vec_idx].
desc[strlen(ioa_cfg->vectors_info[vec_idx].desc)] = 0;




Сейчас я её упрощу и сразу станет понятно, что здесь что-то не так:

S[strlen(S)] = 0;



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

Бесконечное ожидание



static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev)
{
int i = 0;

while (i < 10) {
if (i)
ssleep(1);

if (ql_sem_lock(qdev,
QL_DRVR_SEM_MASK,
(QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index)
* 2) << 1)) {
netdev_printk(KERN_DEBUG, qdev->ndev,
"driver lock acquired\n");
return 1;
}
}

netdev_err(qdev->ndev,
"Timed out waiting for driver lock...\n");
return 0;
}




Предупреждение PVS-Studio: V654 The condition 'i

Функция пытается залочить драйвер. Если это не получается, она ждёт 1 секунду и повторяет попытку. Всего должно быть сделано 10 попыток.


Но, на самом деле, будет бесконечное количество попыток. Причина в том, что переменная 'i' нигде не увеличивается.


Неправильная информация об ошибке



static int find_boot_record(struct NFTLrecord *nftl)
{
....
if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
SECTORSIZE + 8, 8, &retlen,
(char *)&h1) < 0) ) {
printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, "
"but OOB data read failed (err %d)\n",
block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
continue;
....
}




Предупреждение PVS-Studio: V593 Consider reviewing the expression of the 'A = B

Если возникнет ошибка, функция должна распечатать о ней информацию. В том числе должен быть распечатан код ошибки. Но, на самом деле, будет распечатано (err 0) или (err 1), а не настоящий код ошибки.


Причина — программист запутался в приоритетах операции. В начале он хотел поместить результат работы функции nftl_read_oob() в переменную 'ret'. Затем он хочет сравнить эту переменную с 0. Если (ret < 0), то нужно распечатать сообщение об ошибке.


На самом деле, все работает не так. В начале результат работы функции nftl_read_oob() сравнивается с 0. Результатом сравнения является значение 0 или 1. Этот значение будет помещено в переменную 'ret'.


Таким образом, если функция nftl_read_oob() вернула отрицательное значение, то ret == 1. Будет выведено сообщение, но неправильное.


В условии видно, что используются дополнительные скобки. Неизвестно, были они написаны чтобы подавить предупреждение компилятора о присваивании внутри 'if' или чтобы явно указать последовательность операций. Если второе, то мы имеем дело с опечаткой — закрывающаяся скобка стоит не на своём месте. Правильно будет так:



if ((ret = nftl_read_oob(mtd, block * nftl->EraseSize +
SECTORSIZE + 8, 8, &retlen,
(char *)&h1)) < 0 ) {




Подозрение на опечатку



int wl12xx_acx_config_hangover(struct wl1271 *wl)
{
....
acx->recover_time = cpu_to_le32(conf->recover_time);
acx->hangover_period = conf->hangover_period;
acx->dynamic_mode = conf->dynamic_mode;
acx->early_termination_mode = conf->early_termination_mode;
acx->max_period = conf->max_period;
acx->min_period = conf->min_period;
acx->increase_delta = conf->increase_delta;
acx->decrease_delta = conf->decrease_delta;
acx->quiet_time = conf->quiet_time;
acx->increase_time = conf->increase_time;
acx->window_size = acx->window_size; <<<---
....
}




Предупреждение PVS-Studio: V570 The 'acx->window_size' variable is assigned to itself. acx.c 1728

Везде поля одной структуры копируются в поля другой структуры. И только в одном месте вдруг написано:



acx->window_size = acx->window_size;



Это ошибка? Или так и задумывалось? Я не могу дать ответ.

Подозрительное восьмеричное число



static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = {
{0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400,
640x200,640x400) */
{0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */
{0, 648, 448, 405, 96, 2}, /* 02 (360x400,720x400) */
{0, 648, 448, 355, 96, 2}, /* 03 (720x350) */
{0, 648, 1, 483, 96, 2}, /* 04 (640x480x60Hz) */
{0, 840, 627, 600, 128, 4}, /* 05 (800x600x60Hz) */
{0, 1048, 805, 770, 136, 6}, /* 06 (1024x768x60Hz) */
{0, 1328, 0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */
{0, 1438, 0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)*/
{0, 1664, 0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */
{0, 1328, 0, 0771, 112, 6} /* 0A (1280x768x60Hz) */
^^^^
^^^^
};




Предупреждение PVS-Studio: V536 Be advised that the utilized constant value is represented by an octal form. Oct: 0771, Dec: 505. vb_table.h 1379

Все числа в этой структуре заданы в десятичном формате. И вдруг встречается одно восьмеричное число: 0771. Анализатор это насторожило. И меня тоже.


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


Подозрительная строка



static void sig_ind(PLCI *plci)
{
....
byte SS_Ind[] =
"\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
byte CF_Ind[] =
"\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
byte Interr_Err_Ind[] =
"\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
byte CONF_Ind[] =
"\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
^^^^^^^^^^^^^^^^^^^
....
}




Предупреждение PVS-Studio: V638 A terminal null is present inside a string. The '\0x00' characters were encountered. Probably meant: '\x00'. message.c 4883

В массивах содержатся некие магические значения. Подозрение вызывает содержимое массива CONF_Ind[]. В нем чередуются нулевые символы с текстом «x00». Мне кажется, это опечатка и, на самом деле, должно быть написано так:



byte CONF_Ind[] =
"\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00";




Т.е. '0' перед 'x' лишний и написан случайно. В результате «x00» интерпретируется как текст, а не как код символа.

Подозрительное форматирование кода



static int grip_xt_read_packet(....)
{
....
if ((u ^ v) & 1) {
buf = (buf << 1) | (u >> 1);
t = strobe;
i++;
} else

if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) {
....
}




Предупреждение PVS-Studio: V705 It is possible that 'else' block was forgotten or commented out, thus altering the program's operation logics. grip.c 152

Я не думаю, что здесь есть ошибка. Но код отформатирован очень плохо. Поэтому и привожу его в статье. Лучше лишний раз проверить.


Неопределённое поведение в операциях сдвига



static s32 snto32(__u32 value, unsigned n)
{
switch (n) {
case 8: return ((__s8)value);
case 16: return ((__s16)value);
case 32: return ((__s32)value);
}
return value & (1 << (n - 1)) ? value | (-1 << n) : value;
}




Предупреждение PVS-Studio: V610 Undefined behavior. Check the shift operator '

Сдвиг отрицательных значений приводит к неопределённому поведению. Про это я много раз писал и не буду останавливаться на этом подробно. Тем, кто не знает в чём тут дело, предлагаю для ознакомления статью "Не зная брода, не лезь в воду. Часть третья (про сдвиги)".


Предвижу возражение в духе: «но ведь работает!». Возможно и работает. Но, я думаю, ядро Linux это не то место, где можно полагаться на такой подход. Код лучше переписать.


Таких сдвигов весьма много, поэтому я собрал их в отдельный файл: Linux-V610.txt.


Путаница с enum




Есть вот такой два enum:

enum iscsi_param {
....
ISCSI_PARAM_CONN_PORT,
ISCSI_PARAM_CONN_ADDRESS, <<<<----
....
};

enum iscsi_host_param {
ISCSI_HOST_PARAM_HWADDRESS,
ISCSI_HOST_PARAM_INITIATOR_NAME,
ISCSI_HOST_PARAM_NETDEV_NAME,
ISCSI_HOST_PARAM_IPADDRESS, <<<<----
ISCSI_HOST_PARAM_PORT_STATE,
ISCSI_HOST_PARAM_PORT_SPEED,
ISCSI_HOST_PARAM_MAX,
};




Обратите внимание на константу ISCSI_PARAM_CONN_ADDRESS и ISCSI_HOST_PARAM_IPADDRESS. Их названия похожи. Видимо, это и стало причиной путаницы.

Рассмотрим фрагмент кода:



int iscsi_conn_get_addr_param(
struct sockaddr_storage *addr,
enum iscsi_param param, char *buf)
{
....
switch (param) {
case ISCSI_PARAM_CONN_ADDRESS:
case ISCSI_HOST_PARAM_IPADDRESS: <<<<----
....
case ISCSI_PARAM_CONN_PORT:
case ISCSI_PARAM_LOCAL_PORT:
....
default:
return -EINVAL;
}

return len;
}




Предупреждение PVS-Studio: V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B:… }. libiscsi.c 3501

Константа ISCSI_HOST_PARAM_IPADDRESS не относится к enum iscsi_param. Скорее всего это опечатка, и должна использоваться константа ISCSI_PARAM_CONN_ADDRESS.


Аналогичные предупреждения PVS-Studio:



  • V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B:… }. svm.c 1360

  • V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B:… }. vmx.c 2690

  • V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B:… }. request.c 2842

  • V556 The values of different enum types are compared: switch(ENUM_TYPE_A) { case ENUM_TYPE_B:… }. request.c 2868




Странный цикл




Здесь я не смогу показать фрагмент кода. Фрагмент большой, и я не знаю, как его сократить и красиво отформатировать. Поэтому я напишу псевдокод.

void pvr2_encoder_cmd ()
{
do {
....
if (A) break;
....
if (B) break;
....
if (C) continue;
....
if (E) break;
....
} while(0);
}




Цикл выполняется 1 раз. Есть подозрение, что такая конструкция создана для того, чтобы обойтись без оператора goto. Если что-то пошло не так, вызывается оператор 'break', и начинают выполняться операторы, расположенные после цикла.

Меня смущает, что в одном месте написан оператор 'continue', а не 'break'. При этом работает оператор 'continue', как 'break'. Поясню.


Вот что говорит стандарт:


§6.6.2 in the standard: «The continue statement (...) causes control to pass to the loop-continuation portion of the smallest enclosing iteration-statement, that is, to the end of the loop.» (Not to the beginning.)


Таким образом, после вызова оператора 'continue' будет проверено условие (0), и цикл завершится так как условие ложно.


Возможно 2 варианта.



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

  2. Оператор 'continue' должен по задумке программиста возобновлять цикл. Тогда код некорректен и его следует переписать.




Copy-Paste ошибка



void dm_change_dynamic_initgain_thresh(
struct net_device *dev, u32 dm_type, u32 dm_value)
{
....
if (dm_type == DIG_TYPE_THRESH_HIGH)
{
dm_digtable.rssi_high_thresh = dm_value;
}
else if (dm_type == DIG_TYPE_THRESH_LOW)
{
dm_digtable.rssi_low_thresh = dm_value;
}
else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) <<--
{ <<--
dm_digtable.rssi_high_power_highthresh = dm_value; <<--
} <<--
else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) <<--
{ <<--
dm_digtable.rssi_high_power_highthresh = dm_value; <<--
} <<--
....
}




Предупреждение PVS-Studio: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 1755, 1759. r8192U_dm.c 1755

Код писался с помощью Copy-Paste и в одном блоке текста забыли заменить:



  • DIG_TYPE_THRESH_HIGHPWR_HIGH на DIG_TYPE_THRESH_HIGHPWR_LOW

  • rssi_high_power_highthresh на rssi_high_power_lowthresh


Плюс прошу разработчиков посмотреть сюда:

  • V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 1670, 1672. rtl_dm.c 1670

  • V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical error presence. Check lines: 530, 533. ioctl.c 530




Повторная инициализация




Есть странные места, где переменной два раза подряд присваивают разные значения. Думаю, стоит проверить эти участки кода.

static int saa7164_vbi_fmt(struct file *file, void *priv,
struct v4l2_format *f)
{
/* ntsc */
f->fmt.vbi.samples_per_line = 1600; <<<<----
f->fmt.vbi.samples_per_line = 1440; <<<<----
f->fmt.vbi.sampling_rate = 27000000;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
f->fmt.vbi.offset = 0;
f->fmt.vbi.flags = 0;
f->fmt.vbi.start[0] = 10;
f->fmt.vbi.count[0] = 18;
f->fmt.vbi.start[1] = 263 + 10 + 1;
f->fmt.vbi.count[1] = 18;
return 0;
}




Предупреждение PVS-Studio: V519 The 'f->fmt.vbi.samples_per_line' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1001, 1002. saa7164-vbi.c 1002

static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
{
....
/* Init and establish defaults */
params->samplesperline = 1440;
params->numberoflines = 12; <<<<----
params->numberoflines = 18; <<<<----
params->pitch = 1600; <<<<----
params->pitch = 1440; <<<<----
params->numpagetables = 2 +
((params->numberoflines * params->pitch) / PAGE_SIZE);
params->bitspersample = 8;
....
}




Предупреждения:

  • V519 The 'params->numberoflines' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 118, 119. saa7164-vbi.c 119

  • V519 The 'params->pitch' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 120, 121. saa7164-vbi.c 121


Заключение




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

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


Linux and PVS-Studio


Предлагаю всем желающим попробовать PVS-Studio на своих проектах. Анализатор работает в среде Windows. Если кто-то хочет использовать его при разработке крупных Linux приложений, то напишите нам, и мы обсудим возможные варианты заключения контракта по адаптации PVS-Studio для ваших проектов и задач.


Эта статья на английском




Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. PVS-Studio dives into Linux insides (3.18.1).

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


[Из песочницы] Закон Фиттса или как его использовать

Здравствуйте, хабровчане!

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


Для начала приведем формулировку закона Фиттса:

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


Формула:

T = a + b * log ( D / W + 1 ),


где T — время работы пользователя с меню в (мс), a и b — коэффициенты навыков и умений работы пользователя с тем или иным устройством, D — расстояние от одного до другого пункта меню, W — ширина пункта меню при движении к нему от другого пункта меню.


Для большего понимания представим расчетную схему:




Рисунок — Расчетная схема закона Фиттса.


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


Рассчитаем среднее время для паркетного меню с параметрами: p1=120 px, p2=160 px, d=10 px, n=6, где n – количество пунктов меню.

Получим таблицу, в которой указаны параметры Wi, Di, Ti.




















































iWiDiTi
1143.323193.484329.433
2131.39152.678316.512
3143.323193.484329.433
4143.323193.484329.433
5131.39152.678316.512
6143.323193.484329.433
Среднее значение115.458147.634324.657

Результаты таблицы показывают, что для повышения эффективности взаимодействия пользователя с паркетным меню наиболее часто выбираемые элементы должны быть расположены под №2 и №5.


В качестве практического примера рассмотрим такую задачу: необходимо построить паркетное меню, которое будет состоять из 6-ти элементов с определенными наименованиями, а именно — Моя страница, Мои партнеры, Мои заказы, Сообщения, Мои компании, Люди. Приведем таблицу вероятности выбора каждого пункта меню.



























1. Моя страница0.25
2. Мои партнеры0.17
3. Мои заказы0.15
4. Сообщения0.13
5. Мои компании0.1
6. Люди0.2

В данном примере условием для расчета является не равновероятный выбор произвольного пункта меню, таким образом, расчет D и W будет изменен с учетом вероятности.


Расположим пункты меню в двух вариантах последовательно, как показано на расчетной схеме:


Первый вариант: Моя страница -> Сообщения -> Мои заказы -> Люди -> Мои компании -> Мои партнеры

Второй вариант: Сообщения -> Моя страница -> Мои заказы -> Мои компании -> Люди -> Мои партнеры


Результаты для первого варианта: D = 184.098 px, W = 140.578 px, T = 326.744 мс

Результаты для второго варианта: D = 175.121 px, W = 137.953 px, T = 324.026 мс


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


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


Спасибо за внимание!


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


Список литературы




1. Статья Википедии / Usability / goo.gl/DJM3OP

2. Статья Википедии / Закон Фиттса / goo.gl/worZ3z

3. Губко М.В., Даниленко А.И Математическая модель оптимизации структуры иерархического меню // Проблемы управления. — 2010. — №4. — С.49-58.

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Как надо дружиться с STM32

Не, не, не, все не так!

Давайте дружиться с STM32 правильно!


Самая главная ошибка, сделанная автором — это неправильно выбранный инструментарий. Начинать дружить с контроллерами STM32 надо, безусловно, с плат STM32Fx-Discovery. На них уже есть программатор-отладчик, весь необходимый обвес, ноги для подключения периферии и плюшки в виде светодиодов, экранов, датчиков и ЦАП-ов в зависимости от платы. Цена дискаверей начинается от 10 долларов. Это копейки за мгновенный и безпроблемный старт. Т.е. вам вообще ничего больше из железа покупать не надо (mini-USB шнур, полагаю, дома найдется), чтобы помигать светодиодом, изучить системы пространственной ориентации, поработать с выводом звука и графики и сделать USB-устройство.


Дополнительный бонус — программатором с дискавери можно программировать внешние МК, разъем для этого есть на плате.


Но, допустим, не лежит у вас душа к дискавери. Ладно, я понимаю. Смотрим тогда, на чем же построены отладчики ST-Link V1/V2. А построены они на микроконтроллере STM32F103C8T6 (eta4ever, да, да, он самый). Соответственно, если у тебя есть плата на этом МК, то ее можно превратить в программатор ST-Link V2. Для заливки прошивки можно воспользоваться либо инструкцией от STM (AN2557 STM32F10x in-application programming using the USART) или той же дискавери, если есть под рукой и утилитой STM32 ST-LINK utility. Или купите отладчик. Стоит он 25 долларов, но вещь полезная, если собираетесь хоть сколько серьезно этим заниматься.


Кстати, еще насчет платы. Китайцы продают много готовых плат, вроде вот таких. Платка такая за 6 долларов — совсем неплохо. Лучше только такая платка за 4 доллара. Итак, заказываем такие платки, после получения превращаем одну в программатор, а с остальными развлекаемся. Ну не сказка ли?


Итак, как же сделать программатор? Пара резисторов, немножко провода и пятнадцать минут почитать вот эту тему. Что с чем соединять:



— соединить РА5 и РВ13 это линия SWCLK

— между РВ14 и РВ12 резистор 220 Ом

— РВ14 линия SWDIO

— РА0 подключить к делителю из двух резюков 4,7кОм между GND и +3,3V





Прошиваем вот этой прошивкой.

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


Пару слов про IDE. CooCox неплох, удобный и все такое, но у них очень туго с ресурсами и они не успевают поддерживать новые микроконтроллеры, да еще к тому же у них приоритет, похоже, LPC. Я так нарвался с поддержкой МК на плате STM32F0-Discovery. Ждал обещанной поддержки несколько месяцев, но плюнул и ушел на IAR. Иаровская среда называется EWARM (Embedded Workbench for ARM), бесплатной версии хватает за глаза (ограничение кода 8 кб, я ни разу не утыкался в него), скачивается отсюда. Еще КуКокс грешит тем, что они ломают что-то периодически в новых релизах и стабильность среды невысокая — может просто закрыть все окна без сохранения изменений. Кто в общаге не жил, где свет вырубался раз в час и не имеет привычки нажимать Ctrl+S каждые 30 секунд, может попасть очень сильно. IAR тоже не без грехов, в первую очередь бесит уродская разметка кода и отсутствие выделения активного/неактивного кода в зависимости от директив препроцессора, но жить с этим можно. Важно, что просто так взять и построить проект под STM32 не выйдет (извините, не буду вставлять картинку с Боромиром). Если захотите, напишу подробную степ-бай-степ инструкцию (с картинками!) про то, как создать свой собственный проект с нуля.


P.S. А все-таки, дикавери! Потому что на чем-то еще взять и вот так с нуля сделать фиг получится:



This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Философия программирования — трёхнаправленное программирование

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

Собственно разделение на кодирование, и создание алгоритмов это уже специфика, сначала идёт жизнь, то есть человек опирается на некую мысль вроде «напишу-ка я фреймворк с такими-то свойствами». И вот это начальное направление это вопрос философии. Проблема в том, что часто жена программиста лучше его самого знает, на философском уровне, что он делает и почему. Элементарные философские категории: мышление, сознание, обусловленность программисту неведомы. И это странно, если сравнить способность программиста мыслить, например, читая статьи по функциональному программированию или алгоритмам поиска, вперемешку со статьями видных или русских европейских философов, окажется, что собственно навык мышления у программистов развит не меньше, а то и больше. Вот только язык программиста очень богат пока он рассуждает о паттерн-матчинге и жалок и органичен когда ему надо выйти из своей песочницы, оторваться от IDE и файлового менеджера.



Прагматизм одна из вершин философии. Так же как и марксизм в своё время заявил, что путаница в вопросах сознания непреодолима, и призвал рассуждать в терминах экономики, сводимых к натуральным числам — прагматизм сужает поле ещё дальше и призывает решать очевидные проблемы самым эффективным образом. В этом смысле программист как философ близок прагматизму.


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


Например такая история:



пытаясь раскрасить карту округов Англии, Францис Гутри сформулировал проблему четырёх красок, отметив, что четырёх цветов достаточно, чтобы раскрасить карту так, чтобы любые два смежных региона имели разные цвета. Его брат передал вопрос своему учителю по математике, Огастесу де Моргану, который упомянул о нем в своём письме Уильяму Гамильтону в 1852 году. Артур Кэли поднял эту проблему на встрече Лондонского математического сообщества в 1878 году. В том же году Тэйтом было предложено первое решение этой задачи.



Понимаете? Социальное измерение. То есть вы учите не только код, но вы и знаете имена тех кто этот код придумал, вы не изучаете просто язык Си, но и историю его создания. Это даёт возможность двигаться дальше в исторической перспективе, даёт вам возможность осознать своё местонахождение в социальной структуре и найти где приложить свои силы в новом для всего человечества направлении. Русские постоянно изобретают новые языки программирования и алгоритмы, с этим нет проблем, просто из-за незнания истории и философии программирования вы изобретаете то, что уже изобретено. Либо, что ещё хуже вы изобретаете что-то новое, но не имеете понятия, куда это деть, какому «Лорду Гамильтону» написать о своей работе, и на каком «заседании лондонского клуба» зачитать доклад. Доклад-то вы напишете, и он, скорее всего, будет совершенен с технической точки зрения.


Хотя истемная инженерия подразумевает анализ и постановку задачи перед собственно проектированием, алгоритмированием, разработкой структур данных, кодированием и отладкой, но задачу-то ставит заказчик. Заказчик это «Господь Бог» в философии программирования, он не осмысляется, поскольку не может быть осмыслен, он — абсолют и высшая сила. Можно только осмыслять его отдельные указания и жаловаться на несовершенство «божьих творений». Сами отношения программиста и заказчика в учебнике по Java не поднимают, это марксизм или протестантская этика: метафизика подчинения и обусловленность материальными ценностями. В америке есть класс «супер программистов», «старт-аперов», люди не имеют заказчика, они знают жизнь настолько, что сами могут увидеть потребности. То есть он не сидит и не ждёт пока некто, кто в жизни разбирается лучше него, придёт и скажет ему, что ему делать, он сам осмысляет жизнь и находит куда двигаться чтобы заработать и реализоваться как деятель. Не пишет программу, которую люди запрашивают, а сам создаёт запрос и сам же его удовлетворяет. Был ли запрос на iphone когда Джобс его придумал? Или Джобс создал сам запрос?


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


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


Есть поговорка, что человеку свойственна итерация, а Богу — рекурсия. В поиске истины давно нет правильного направления, люди разбрелись, релятивизм, плюрализм. Когда мы ссылаемся на какой-то объект, наше высказывание сразу само становится объектом, на который можно ссылаться, а можно вообще перейти на личность, так мы получим в любом обсуждении, в комментах, сразу проявления постмодернизма (замена объекта ссылкой) и феноменализма — переход на личность в попытке избежать утопания в графе смыслов.


Соответственно плюрализм в выборе ЯП, среды разработки, фреймворка, это тяготение к одному полюсу. А желание пользоваться таким-же ЯП, фреймворком, что и многие другие люди — это коллективизм, проявление атомизации, отчуждения. Программист очень одинок и одновременно перегружен общением. Это непаханое поле для исследований. Высшая нервная деятельность, работа со структурами и текстом, изучение языков — и это как обычная ежедневная деятельность. Программист удивил бы людей девятнадцатого века ёмкостью и силой своей мысли. Он бы удивил и людей двадцать первого, если бы мог с ними общаться на том уровне на котором он ежедневно работает. Тем удивительнее слепота программиста. Программиста часто отличают по внешнему виду. И это не дресс-код, человек просто не обращает внимания как выглядит и во что одет. То есть он знает что на нём одето, но почему именно оно или даже как оно правильно называется это для него далёкий космос. Вы знаете чем свитер от пуловера отличается? Джемпер от кофты? А зачем мне?


Программист это как раб лампы, как батарейка матрицы — если он вдруг начнёт применять свой мозг, свои невиданные способности по оперированию языками, логикой, работой с объёмами данных в обычной жизни — он может стать тем самым одноглазым, который король в стране слепых. Свитер облегает шею и тело, пуловер имеет широкое отверстие чтобы его было удобнее натягивать (pull-over), кофта имеет пуговицы. У джемпера вместо широкого отверстия застёжка. Это элементарно, можно написать в одну строчку кода. Но программисту не понятно одно, что эта информация, это не про одежду, это — часть описания жизни. Правда европейцы часть отличаются, есть культура программировать жизнь, особенно у англичан. Давно они открыли, что можно написать какое-то письмо, например «высылаю вам три мешка сукна, вышлите мне шесть золотых» и вдруг это можно повторять снова и снова и появляется возможность управлять жизнью просто сидя за своим рабочим столом и сочиняя письма. Венеция, Ганза, Кембрия. Это качество унаследовали и американцы, и поскольку они же полюбили и компьютеры и программирование они вышли на недосягаемый уровень. Они видят третий вектор программирования: любой код, любая программа программирует не только компьютер, не только процессор, но и пользователей.


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


Трёхнаправленное программирование. Компьютер, программист, пользователь. Невозможно внести изменения в код, не внеся изменения в будущее пользователя и программиста. Но можно об этом не думать. Так проще. Не думать — всегда проще. Человек из всех входных сигналов предпочитает принимать те, которые не требуют осмысления, а лишь ощущения. Вкус пива, чистая рубашка, похвала, или даже оскорбления и наезд начальства. Из этих эмоций далее следует эмоциональное принятие решений. Приятный фреймворк. Идиотский язык программирования. Тупой коммент. Классная статья. У меня возникла идея написать свою реализацию b-trees. Почему? Ну понравилась идея. Общение программистов, самых логически занятых сознаний, сводится к обмену эмоциями. Это два бурлящих потока, сталкиваются, отталкиваются, создают вихри — как же они вообще могут программировать? Очень просто, после часа эмоций они расходятся чтобы читать книги. Тут включается мысль. Киньте ссылку, я почитаю. Мне понравилось, есть что-нибудь почитать по этой теме? Две жизни. Программист особенно интересен тем, что для него даже кодирование это эмоциональное занятие, он бросает свои чувства в холодный экран, он пытается почуять логику и оформить себя как разум в результате. Русским программистам это особенно свойственно, а не свойственно им — рассуждать, тем более вслух, тем более письменно. Более того, человек способный рассуждать о своём проекте вызывает недоверие — он кажется вруном, который вместо того, чтобы смотреть в код, осознавать структуру алгоритма, почему-то думает о социальных проявлениях, пиарится, — сказки про Эльбрус и Фантом.


Поэтому в России нет Open Source. Потому что опенсорс это не умение программировать, это умение общаться. Это знание истории программ и программистов. Вы можете выложить на гитхаб своё творение, и даже написать к нему статьи и инструкции, но некому этого будет читать. Или они прочитают и напишут «хочу присоединиться к проекту, только не знаю, что делать». «Студент, немного знаю Яву, очень интересный проект, скажите, что делать». Почему американский студент «знающий Яву» сразу знает, что делать? Почему он может создать один опенсорс проект и присоединится к другому? Вопрос более социальный чем философский, наш социум в другом состоянии. Но философу ясно, — человек не осознаёт себя. Как говорит Гузеева в «Давай поженимся» — «ничего про себя не понимает». Он сидит в своей комнате за компом, мама ему говорит, «ну что ты у меня такой к жизни неприспособленный». «Ой, отстала бы ты, сама что ли умная». Но мама умная, это ты дурак. Точнее у неё другие входные сигналы, ты смотришь в монитор, она смотрит по сторонам. Даже отставая интеллектуально, в навыках логики и работы с информацией, наличие обширных входных сигналов из жизни, о людях, о взаимоотношениях — делает человека понимающим жизнь лучше программиста.


Мама не дура, даже по одежде и тарелкам может твоё будущее предсказать не зная асинхронной обработки данных. Это не сложно, и ты бы мог, если бы смотрел на социум и знал язык описания и программирования. По инстанциям похлопотать. Растёт ценный кадр. Толковый парень появился. Выправить документы. Начальство приметило. Это API. Ничего сложного. Программисты могут и должны править миром. Но пока что, только небольшой слой американский программистов это понял. Гейтс понял, что программа может глючить когда её инструкции выполняются в компьютере, но она не должна глючить, когда её инструкции выполняет пользователь. Это не только цинизм, это понимание своей роли, это исследование поведения, это изучение API пользователя и всего общества. Нажми сюда, что будет если пользователь нажмёт эту кнопку? А если тут введён текст, как сделать, чтобы он ввёл текст и сюда? Открылось окно выбора файла, в какой папке по умолчанию оно должно быть открыто? Сколько часов вы потратили на отладку кода, почему вы не потратили в десять раз больше изучая поведение пользователя? Гейтс потратил.


Люди записывают на видео поведение пользователя за программой, причём с момента входа в комнату. Самое смешное, что эти люди это не программисты, это приглашенные люди — социологи, даже дрессировщики. Они сидят и выполняют работу, которую по идее программист должен выполнить эффективнее, ведь это отладка кода. Вносятся изменения. Но программа работает не быстрее после этих изменений, она может быть работает медленнее и чаще глючит, в процессоре, на компе глючит, но в поведении пользователя она работает лучше, он быстрее выполняет операции (performance), чаще достигает цели (debug), он доволен (energy saving). Он платит в конце концов. Всё, что делал Джобс — это программирование пользователя. Как он к этому пришёл? культура окружения? наркотики? личный талант? Философия. Канты-гегели, Гуссерли-расселы, Витгенштейны-сартры, тысячи их. Они создали немало языков для описания реальности и API для её осмысления. Большинство умных слов которыми мы пользуемся интуитивно, было ими некогда введено и сформулировано. Нельзя употреблять слово «культура» и думать о консерватории, говорить «консерватория» и не знать, что это в первую очередь система преподавания и отбора преподавателей. Консервативная и консервирующая опыт. Для программиста, всё чем он пользуется взялось из ниоткуда. Умные люди разберутся, преподы в универе есть для этого.


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


Вы смеётесь, что американцы не могут на глобусе найти Ирак. А вы над собой посмейтесь, вы можете на глобусе истории логики найти Гегеля? Вы пользуетесь BASH, вы знаете, кто и когда его создал и как он осмысляет своё творение по прошествии десятков лет? Вы знаете почему терминал называется терминал? Как он связан с телетайпом? Вы знаете, что компания IBM делала перепись населения в США более ста лет назад на деньги центробанка, а потом поставила эти механические компьютеры Гитлеру? Вы представляете, что устройство и терминология баз данных ведёт историю от тех перфокарт, а они от каталогизаторов привезённых из Англии в начале девятнадцатого века? Вы знаете как создатель Atari Бушнел не понял идеи своего работника Джобса? Вы хотя бы представляете роль Atari в истории вычислительной техники? Кто кого скопировал Atari или Sinclair? Мало знать устройства и их историю, надо в первую очередь знать людей, мысли и их историю. Отец Гёделя был священником, а отец Святого Франциска был банкиром и торговцем. Что такое львовско-варшавская школа логики?


Ну ладно, это ваше трёхнаправленное программирование, понятно, надо знать не только код и язык программирования, но и историю языка, знать себя и пользователя и историю и языки, ну а как же отладка? А что отладка? Зачем вообще нужен отладчик? Просто вы ещё не умеете мыслить, вы всё ещё реагируете и ждёте подсказок, вы не понимаете свою программу, вы останавливаете её и ждёте, что отладчик вам что-то покажет. Тогда, надеетесь вы, в голове появятся идеи. «В вашем отладчике неудобно ставить брэкпойнты.» Метапрограммирование это когда программа создаёт программу, тоже своего рода рекурсия. Так же и программа может дебажить программу, мета-отладка, но для этого программист должен быть в два раза умнее, он должен удерживать в голове сразу две программы. Люди которые используют printf() и смеются над отладчиками, просто лучше понимают, что делают.


Кстати, линковщик тоже не нужен, рудимент первых трансляторов. А типизированые языки нужны только потому, что из ста программистов только один умеет программировать, остальных нужно за ручку водить. Даже одна обезьяна напечатает «Войну и мир», если разблокировать только нужные клавиши и в нужном порядке. Потому мы так и любим подсветку синтаксиса и темы оформления — это способ воздействовать на себя, на свой разум, сконцентрировать внимание, помочь себе видеть больше. Сейчас размываются границы, где встроенная документация, где интернет, где компилятор, где интерпретатор, где ходить на работу, а где самозанятость. В таких условиях желание опереться на авторитет развивается, как у ребёнка желание схватить взрослого за рукав. Преданный взгляд в глаза Google когда они выкатывают очередную технологию для разработчиков. Надо вставать на ноги и осмотреться в большом взрослом мире, где ты не изучаешь технологии, а создаёшь их, где ты видишь не только мануал, но и руку которая тебе его протягивает и знаешь историю обоих. Это основы, это называется философия программирования.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


пятница, 2 января 2015 г.

Тренды JavaScript на 2015 год


Всем привет! Мы как-то задумали сделать легкий вводный курс на тему JavaScript и разработки приложений (он, кстати, скоро будет опубликован): и, пока я собирал материалы к нему, как-то само собой выяснилось, что есть довольно много вещей, которые, так сказать, находятся на переднем крае развития JavaScript. Отсюда родилась идея сделать отдельную обзорную статью в жанре «X трендов на год Y по технологии Z».


Многие из тех, вещей, которые я буду описывать, можно попробовать в той или иной степени уже сегодня (собственно, иначе я бы говорил о космическом будущем, а не о трендах). В этом есть несомненный плюс: если у вас будет свободное время (а на праздниках его обычно много), вам будет чем заняться. Да и, в целом, хорошо начинать новый год с расширения своих горизонтов!


1. ECMAScript 6






Если вы занимаетесь веб-разработкой, вы наверняка на себе прочувствовали все прелести и ограничения JavaScript. Когда Брендан Айк в 1995 году придумывал на скорую руку JavaScript, навряд ли он мог предположить, во что разовьются через 15-20 лет веб-технологии и какие фокусы разработчики будут вытворять, используя его детище.

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


Новый стандарт (который, кстати, в пику несостоявшемуся выпуску ES4 иногда называют как ES6 “Harmony”) несет давно ожидаемые возможности, которые существенно облегчат создание сложных решений: классы, модули, коллекции, итераторы, генераторы, прокси, типизированные массивы, обещания, новые методы и свойства для стандартных объектов и новые синтаксические возможности и еще много чего.



// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;

// app.js
module math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));


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


Писать и поддерживать сложные приложения станет сильно проще. Посмотреть, как выглядят новые фишки языка в коде можно в обзоре “Overview of ECMAScript 6 features” от Luke Hoban.


Следить за внедрением поддержки новых возможностей ES6 можно по таблице совместимости с ES6. А попробовать многие возможности уже сейчас можно в свежей сборке Internet Explorer Technical Preview, доступной в рамках программы Windows Insider.


Кстати, в конце 2015 нас ждет большой праздник – 20-летие JavaScript. Фактически, новый стандарт – это попытка сделать JavaScript хорошим языком (хотя некоторые его концепции навряд ли покажутся новичкам более легкими, чем прототипное наследование). А еще есть прогноз, что стандарт ES6 будет утвержден именно в 2015 году. Впрочем, непосредственное внедрение нового стандарта в практику разработки займет не один год.


Что ждать в 2015: новый стандарт ECMAScript 6, реализация в браузерах, адаптация в сообществе и фремворках.


2. Типизированный JavaScript






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

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


Как на зло, оказалось, что работа с файлами и графикой (привет WebGL!) требуют умения работать с типами конкретной размерности, а не единым обобщенным Number, поэтому, кстати, появился отдельный стандарт для типизированных массивов, который теперь станет частью ES6.


В общем, когда за дело взялся Андерс Хейлсберг (Delphi и C# — его детище), появился TypeScript. TS – это надмножество JS, добавляющее в язык статическую типизацию на этапе разработки, а также многие возможности из ES6. Конечно, TS появился не просто так, а в том числе из внутренней потребности Microsoft в удобном создании сложных веб-приложений.



// TypeScript
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}


(Аналогичная потребность созрела и в других компаниях – обратите внимание на новые проекты по типизации от Facebook (Flow) и Google (AtScript). Тут самое место для большой надежды, что в 2015г. мы не получим очередные новые несовместимые технологии.)


Прелесть TypeScript в том, что, пока вы пишите код (особенно если вы делаете это в Visual Studio, но не обязательно), вы получаете возможность удобно описывать сложные структуры данных, а компилятор при этом помогает вам отслеживать, что вы нигде ничего не напутали и правильно работаете с типами.


Еще одно замечательное свойство TS, точнее его компилятора (который, кстати, открыт также, как и сам язык!), состоит в том, что в результате компиляции получается чистый код на JavaScript, причем, примерно такой, какой вы бы и сами написали, следуя современным практикам:



// TypeScript to JavaScript
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();


Таким образом, на выходе получается код, работающий в современных браузерах на любых операционных системах. К слову, под Node.js тоже можно писать на TypeScript.


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


В перспективе следующая большая версия TypeScript 2.0 должна стать надмножеством ES6. Попробовать TS в браузере прямо сейчас можно в нашей песочнице.


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


Что ждать в 2015: рост адаптации TypeScript, развитие альтернативных проектов и их взаимное обогащение.


3. Кросс-платформенность






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

Две ключевые задачи, которые нам предстоит решать в следующем году (и не только): стереть границу между сайтами и приложениями, а также развивать возможности кросс-платформенной разработки приложений на JavaScript.


Стирание границ




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

В контексте Windows и Windows Phone одним из решений в данном направлении является технология WAT (Web Application Template), позволяющая хостить веб-сайты в виде приложений для ОС, доставляемых через магазин приложений. Как результат, сайт «превращается» в приложение: выглядит как нативное приложение (при должной стилизации), ведет себя как нативное приложение (за счет интеграции в ОС) и получает нативные возможности (например, работу с камерой и файловой системой).


Безусловно, это не единственная подвижка в этом направлении: думаю, часть веб-разработчиков с большим опытом помнит проект Mozilla Prism. Из недавней истории – это закрепленные сайты в Windows 7+, из совсем свежей – Яндекс.Браузер, старающийся минимизировать визуальное присутствие браузера.


Несмотря на имеющиеся подвижки, в будущем еще многое предстоит сделать (от облегчения доступа к нативным возможностям до стандартизации соответствующих API, например, в части W3C Manifest for web applications). Это, кстати, может оказаться интересным пространством для технологических инноваций.


Мобильная разработка




Во второй задаче, значительная часть пути уже проделана в таких проектах, как Apache Cordova. За прошедшие пару лет к проекту подключилось множество крупных компаний: сегодня это уже не только Adobe, купивший PhoneGap, но и Microsoft, Intel, IBM, Google и другие.

В определенном смысле, Cordova как раз решает сегодня ту задачу, на которую в мире веб-разработки и веб-стандартов уходит больше времени, чем хотелось бы. А именно: предоставление доступа к нативным возможностям единообразно из JavaScript на разных платформах.


Вы пишите код на HTML/CSS и JS, Cordova упаковывает их в приложение, которое можно распространять через магазины приложений. Важным отличием от предыдущего пункта тут является то, что код такого приложения является локальным, поэтому заведомо обладает большими возможностями. Впрочем, вместе с этим он приобретает и ограничения в смысле обновления только через магазины.


Почему я ожидаю заметного роста в использовании и адаптации Cordova в следующем году? На это есть три важные причины:



  1. Продолжение роста мобильного сегмента и смещения фокуса внимания в сторону приложений (против веб-браузера).

  2. Повышение производительности и возможностей WebView-компонент (стандартный повод говорить, что приложения на JS тормознутые). Это, кстати, критично и для хостинга сайтов.

  3. Появление отличных инструментов, позволяющих удобно разрабатывать, тестировать и собирать приложения под разные платформы. Visual Studio 2015 (Preview) тому отличный пример, но естественно, в этом направлении двигается не только Microsoft.


Интересным моментом в обоих направлениях является то, что если у вас в штате есть JavaScript-разработчик, то в перспективе он может закрывать все основные ниши веб- и мобильной разработки. Да, писать приложения на TypeScript для Apache Cordova и веб-сайтов тоже можно уже сегодня!


Что ждать в 2015: развитие инструментов для кросс-платформенной разработки на JS, продолжение стирания границ между сайтами и приложениями.


4. Native






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

Для многих разработчиков до сих пор такая мысль режет слух. Нативное – это традиционно на C++, C#, ObjectiveC, Java и т.п., но никак не на JavaScript.


У этого было и историческое подтверждение в мобильных платформах, на которых писать на JavaScript можно было только внутри WebView, который был всего лишь одним из элементов управления в рамках приложения на «настоящем» нативном языке. И это было медленно.


Однако ситуация изменилась: Windows 8 с самого начала, Windows Phone с версии 8.1, Firefox OS, Chrome OS и другие платформы уже сегодня предлагают разработку приложений напрямую на JavaScript с прямыми вызовами нативных функций, обращением к файловой системе, интеграцией с возможностями ОС и т.п.



// File system access on Windows platform from JavaScript
// Get folder
var picturesLibrary = Windows.Storage.KnownFolders.picturesLibrary;
// Get folder contents
picturesLibrary.getItemsAsync().then(function (items) {
outputHeader(picturesLibrary.name, items.size);
items.forEach(function (item) {
if (item.isOfType(Windows.Storage.StorageItemTypes.folder)) {
output(id(picturesLibrary.name), item.name + "\\");
}
else {
output(id(picturesLibrary.name), item.fileName);
}
});
});


Все это есть уже сегодня. Вопрос в росте доли соответствующих платформ и осознании веб-разработчиками, что у них есть такая возможность (к слову, это очень интересный психологический аспект, который я часто наблюдаю в рамках экосистемы Windows: даже веб-компании, имеющие в штате достаточное количество веб-разработчиков, предпочитают для Windows-приложений нанимать отдельного разработчика на C#/C++, потому что так принято).


Ситуация постепенно меняется. Удивительно, но одним из направлений роста нативной разработки на JavaScript неожиданно становятся умные телевизоры (например, LG с Open webOS), а также игровые консоли (например, Xbox One). Здесь просто нет альтернативы, а рынок и спрос растет!


Наконец, еще одним важным аспектом является, безусловно, повышение скорости исполнения JavaScript: это и вопрос к компиляторам/интерпретаторам, и к типизации в определенных аспектах, и к выделению подмножества языка, которое можно гарантированно выполнять быстрее (asm.js).


Что ждать в 2015: рост умных телевизоров и консолей с разработкой на JavaScript, адаптация веб-разработчиками возможностей нативной разработки на JS на многих современных платформах (но не всех).


5. Device API






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

С самыми базовыми вещами вроде геолокации или ориентации устройства мы уже научились работать, но впереди большая работа по стандартизации и реализации в движках браузеров (например, за IE можно следить на status.modern.ie) большого блока возможностей, доступных в случае нативной разработки, но, как правило, неподвластных в случае разработки для браузера:



  • Вибрация

  • Статус батареи

  • Сенсоры (например, света)

  • Камера и микрофон

  • и др.


Аналогичная задача стоит и с точки зрения ввода информации со стороны пользователя: начиная с сенсорного ввода (привет Pointer и Touch событиям) и заканчивая управлением голосом и жестами (привет в целом идеям NUI и Kinect, в частности).


Кстати, про Kinect, если у вас есть Kinect for Windows, то вместе с SDK вы получаете и возможность работать с сенсором непосредственно в браузера из JavaScript.


Почему это направление будет развиваться в следующем году? Все просто: разработчики браузеров, тесно связанные с лежащими под ними операционными системами, будут пробрасывать в веб-контекст нативные возможности, а общие устремления должны привести к стандартизации подходов.


Кстати, интересный аспект касательно Apache Cordova, которая в каком-то виде уже это делает: выставляемые проектом API для JavaScript также завязываются на соответствующие стандарты по мере их появления.


Что ждать в 2015: развитие API доступа к нативным возможностям устройства из JavaScript, адаптация NUI в JS. Уверен, это затянется на несколько лет.


6. Борьба со сложностью






Борьба со сложностью, точнее стремление упростить создание сложных решений продолжается. Заканчивается 10-летняя эпоха JS-библиотек, упростивших на долгие годы жизнь веб-разработчиков, заполнявших пробелы между браузерами и недостаточную скорость развития веб-стандартов (кстати, в феврале 2015 будет 10 лет Prototype, если помните такой, в июне – script.aculo.us, а в сентябре — MooTools!).

Какие-то из этих библиотек живы до сих пор и активно развиваются, например, jQuery. Многие умерли или были вытеснены конкурентами.


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


Вслед за решениями для создания приложений на базе концепций MVC (Backbone, Knockout, GWT и т.п.) на рынок вышли новые игроки, двигающиеся еще дальше в сторону создания SPA: Ember.js, Angular (Google), React (Facebook).


Во всем этом движении особенно интересными мне представляются два момента:



  • Выход на рынок крупных игроков, которые переосмысливая свой опыт и свою инфраструктуру создают новых решения (Google и FB тут самые явные примеры). Тут стоит отметить не только инженерный опыт, но и потенциальные маркетинговые рычаги, которые могут перестроить рынок.

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


Как это все будет развиваться дальше?


Во-первых, по мере адаптации и накопления опыта нас ждет переосмысление инженерами своих продуктов и решений. Вторая версия Angular тому хороший пример.


Во-вторых, создание сложных решений требует обновления подходов и, когда возможностей простого JavaScript не хватает, на сцену выходят его доработки. Microsoft переписывает WinJS на TypeScript, Google для Angular 2.0 готовит AtScript, Facebook пишет ReactJS на Flow.


В-третьих, это стремление к совместимости и взаимозаменяемости компонент. Например, в случае WinJS 3.0 – это явное стремление достичь совместимости с другими библиотеками для создания SPA. Хотите использовать WinJS с React? Используйте.


Что ждать в 2015: выход новых переработанных версий популярных библиотек, усиление конкуренции крупных игроков, повышение входного порога для создания комплексных фреймворков, новые возможности для нишевых решений на базе ES6.


7. Веб-компоненты






Веб-компоненты – еще один взгляд на борьбу с нарастающей сложностью. Если ES6 и TypeScript работают на уровне языка, а фреймворки на уровне композиции сложных приложений, то веб-компоненты дают взгляд на то, как справляться со сложностью на уровне элементов HTML и, в частности, объектной модели документа (DOM).

Сегодня веб-компоненты состоят из пяти ключевых компонент:



  • Templates и Decorators – определение и применение шаблонов разметки в связке с данными для динамической генерации элементов HTML (фактически речь идет о стандартизации существующих практик).

  • Custom Elements – создание собственных элементов разметки со своими названиями тегами и необходимыми интерфейсами для JS.

  • Shadow DOM – возможность сокрытия части DOM для отдельных элементов разметки (полезно для виджетов), один из побочных эффектов – наоборот открытие DOM для стандартных элементов управления, стилизация которых обычно затруднена.

  • HTML Imports – упаковка шаблонов и собственных элементов и их внедрение в HTML-документы (здесь есть частичное пересечение с модулями в ES6).


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


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


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


И, конечно, борьба со сложностью в одном месте, безусловно, порождает сложность в каком-то другом. 


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


8. Пакеты и сборка






И как финальный штрих упаковки кода мы подходим к системам сборки и доставки JS-кода. Хотя это разные задачи, в некотором смысле, они начинают и завершают работу с кодом, таким образом, формируя цикл (вплоть до того, что управляются в едином решении вроде Component).

Со сборкой все относительно просто: за последние годы на рынке устоялось несколько лидеров, имеющих в своей основе Node.js. Прежде всего, это Grunt, Gulp и, в меньшей степени, Brunch.


Однако, за год появилось (или стало активнее звучать) и несколько амбициозных проектов, за которыми интересно будет понаблюдать в следующем году: Broccoli, Fez, Mimosa. Навряд ли они существенно потеснят устоявшиеся решения, однако могут занять свои ниши. Ключевая проблема любых новых игроков: наличие сообщества вокруг них, либо сильно драйвера (в том числе маркетингового), который позволил бы им вырваться вперед.


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


Теперь давайте посмотрим на доставку пакетов. Если npm для серверного JavaScript сегодня уже навряд ли кого-то удивишь, то с Bower все только начинается (даже несмотря на то, что Twitter выпустил его с открытым годом аж в 2012 году!). Кстати, не случайно, в Visual Studio появилась встроенная поддержка не только npm, Grunt и Gulp, но и Bower.


На просторах интернета нас ждет все больше и больше строчек вида:



bower install jquery

Оставляя за скобками статьи подробное обсуждение, зачем вам нужен этот менеджер пакетов (кстати, в майском номере Хакера на этот счет была хорошая статья), скажу лишь, что его ключевое отличие от npm в том, что он нацелен именно на клиентскую часть разработки, поэтому если вы занимаетесь фронтэндом и впервые слышите про Bower, самое время его хотя бы попробовать.


Наконец, со стороны загрузки пакетов в браузере, помимо упомянутого ранее Browserify, в 2015 году также будет интересно последить за такими решениями, как Duo (вобравшем в себя идеи не только Browserify, но и Component и Go) и jspm (в частности, уже сегодня реализующем модель модулей ES6).


Что ждать в 2015: адаптация менеджеров пакетов и систем сборки для JavaScript в корпоративной и учебной среде (включая учебники по JS), интеграция в популярные инструменты веб-разработки, возможны новые проекты от крупных игроков.


9. Графика, особенно трехмерная





Сегодня можно уверенно говорить, что не только HTML5 окончательно стал стандартом, но и такие технологии, как WebGL, достигли достаточной зрелости (как с точки зрения безопасности, так и с точки зрения поддержки браузерами).


Поэтому от отрисовки кубиков и чайников и прочих экспериментов мы постепенно переходим ко все более сложным решениями (как правило, игровым). Яркие примеру тому прошлого года – демо-сайт Assassin’s Creed Pirates и сайт Dino Hunt TV.



Важным сдвигом в этом направлении является появление различных библиотек, упрощающих создание решений на базе WebGL, например, three.js и Babylon.js. Аналогичное движение происходит и в мире инфографики – и d3.js тут ярчайший пример.


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



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

  • Игры в социальных сетях: здесь все еще очень большое засилие Flash, но, возможно, если игры в Facebook и VK станут доступными в их мобильных приложениях, то это откроет второе дыхание для игр на HTML/JS.

  • Инфографика и в целом динамичное отображение информации: отчасти эти технологии уже сегодня берут на вооружение новостные сайты.


Кстати, еще пара интересных аспектов:



  • Графическим библиотекам на JS (для Canvas или SVG) предстоит переродиться или кануть в Лету. Связано это с тем, что много из созданного в предыдущие годы, несет в себе заметный груз обратной совместимости, от которого предстоит избавиться, заодно пересмотрев в целом реализацию и возможности библиотек.

  • Развитие инструментов для создания графики и анимации в рамках веб-стека. Традиционно (в смысле наследия от Flash) тут большое внимание стоит уделить продукции Adobe (Edge-семейство) и библиотекам, близким по духу к Flash и ActionScript, например, CreateJS.


Ах да, особенно интересный вопрос на тему графики: рекламный баннеры. Вот уже несколько лет я жду, когда же веб-стандарты придут на смену Flash. Думаю, и в 2015 массового перехода не случится, по крайне мере, до тех пор, пока крупные сети не начнут смену технологий.


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


10. Игры






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

Тут можно предсказать два предстоящих прорыва.


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


Многие движки уже сегодня активно развиваются в этом направлении, но самый большой прорыв 2015 года – это Unity 5 с возможностью исполнения игры или сцены в браузере без дополнительных плагинов. Все это поверх WebGL и JavaScript (через asm.js).


Это событие будет важно не только потому, что Unity3d – один из самых популярных кросс-платформенных движков сегодня, что потенциально означает перенос в веб многих существующих игрушек, но и потому что это станет знаковым событием для WebGL и в целом графики в браузере.


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


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


JavaScript и веб-стек тут может быть подходящим отметом.


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


Что ждать в 2015: Unity 5 с рендерингом в WebGL, развитие 3d и игровых библиотек, потенциальный прорыв через социальные сети.


11. Серверные технологии






На протяжении всей статьи я уже несколько раз упоминал Node.js и это не последний блок, где мы про него вспомним. Node.js на рынке уже более 5 лет (подумать только!), а кажется, что он все еще в новинку.

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


Активная часть сообщества динамична, поэтому с легкостью переключается на новые языки и платформы, однако одно большое преимущество Node.js, от которого мы никуда не денемся – это по-прежнему тот факт, что в нем используется тот же самый язык, что и во всех браузерах – JavaScript, и вместе с ES6 и проектами по типизации JS платформу ждет некоторая встряска.


Помимо адаптации нового стандарта (как я говорил ранее, писать под Node.js на TypeScript можно уже сегодня), нас ждет какое-то развитие еще одного события, которое случилось под конец прошлого года. У Node.js появился форк – io.js. Куда нас заведет это ответвление, пока никто не знает, но приключение обещает быть интересным. Ждем первых релизов в 2015 г.!


Еще один интересный аспект развития Node.js – это тот факт, что платформа наконец-то начала добираться до корпоративной среды. Причем и речь не только о поддержке в промышленных облаках (вроде Microsoft Azure, в том числе использования внутри выставляемых сервисов), но и реальном применении Node.js такими гигантами, как LinkedIn, Yahoo, Walmart (тут стоит упомянуть, что они среди прочего они сделали интересный серверный движок для Node.js – Hapi).


Что ждать в 2015: адаптацию Node.js в корпоративной среде, адаптацию нового ES6 в самом Node.js. Ну и запастить попкорном и смотреть историю с форком.


12. Интернет вещей





Э-ге-гей! Мы добрались до последней темы на сегодня: интернет вещей, он же IoT. Сама по себе история с IoT не нова и навряд ли стоит ожидать, что в 2015 случится что-то более драматичное, чем случилось в 2014 (а в прошлом году ничего драматичного и радикального не случилось) – просто продолжится постепенное развитие направления по всем возможным фронтам: от встраиваемых устройств, умных домов, машин и прочих крупных объектов до сетей мелких сенсоров и носимых устройств.


Какую роль во всем этом играет JavaScript?


Во-первых, для интернета вещей нужно облако и динамичная обработка множества асинхронных событий. А что умеет это неплохо делать? Правильно, Node.js. Конечно, не только он, но и он тоже. В общем, если вы видите будущее в интернете вещей (в той или иной проекции, потому что абстрактно тут делать нечего) и любите JavaScript, то самое время потратить время на разработку соответствующих решений (главное, чтобы у вас была подходящая задача, хотя можно начать и с контроля температуры за окном).


Во-вторых, я снова про Node.js, уже сегодня есть несколько проектов, предлагающих управлять подсоединенными к компьютеру устройствами через JavaScript-код под Node.js. Интересным большим проектом в этом направлении является Cylon.js, уже сегодня поддерживающий кучу устройств. Но есть и маленькие фокусные, например, noduino.


В-третьих, я снова про него, в нескольких умных головах то и дело появляются идеи запускать на «умных вещах» маленький сервер с Node.js. Ну а дальше JavaScript – и в путь. Например, такую идею продвигает Intel в рамках своих платформ Edison и Galileo.



Наконец, в-четвертых, за год на рынке появилось несколько интересных устройств, которые содержат внутри собственный интерпретатор JavaScript и, фактически позволяют программировать себя используя именно JS. Tessel – самый развитый пример, но есть, например, еще Espruino.


Конечно, навряд ли можно рассчитывать, что JavaScript перевернет мир IoT, но вот что адоптация IoT возможна через JavaScript – теперь это чистая правда.


Что ждать в 2015: JavaScript в контексте разных направлений IoT будет следовать за общей динамикой, самое очевидное направление развития – облачные решения на базе Node.js, но также стоит ожидать и новые экспериментальные проекты на клиентской стороне.


Резюме




Напоследок соберем все вместе:


  1. Новый стандарт ECMAScript 6. Утверждение, реализация в браузерах, адаптация в сообществе и фремворках.

  2. Рост использования TypeScript в реальных проектах, развитие альтернативных проектов и их взаимное обогащение.

  3. Развитие инструментов для кросс-платформенной разработки на JS, продолжение стирания границ между сайтами и приложениями.

  4. Рост умных телевизоров и консолей с разработкой на JavaScript, нативная разработка на JS на многих современных платформах (но не всех).

  5. Развитие API доступа к нативным возможностям устройства из JavaScript, адаптация NUI в JS. (Затянется на несколько лет.)

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

  7. Адаптацию веб-компонент браузерами, принятие новых технологий разработчиками элементов управления и различных фреймворков.

  8. Принятие менеджеров пакетов и систем сборки для JavaScript в корпоративной и учебной среде, интеграция в популярные инструменты веб-разработки.

  9. Развитие графических библиотек на JS, показательная адаптация новых технологий крупными или заметными игроками рынка (игры и интерактивный контент — основные драйверы).

  10. Unity 5 с рендерингом в WebGL, развитие 3d и игровых библиотек, потенциальный прорыв через социальные сети.

  11. Адаптация Node.js в корпоративной среде, адаптация нового ES6 в самом Node.js. Запасаемся попкорном и смотрим историю с форком io.js.

  12. Облачные решения для IoT на базе Node.js, новые экспериментальные проекты на клиентской стороне.


Смотря на этот список, я думаю, нас ждет веселый 2015 год!


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.